synchronize原理
synchronized的三种应用方式
一. 修饰实例方法,作用于当前实例加锁,进入同步代码前要获得当前实例的锁。
二. 修饰静态方法,作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁。
三. 修饰代码块,指定加锁对象,对给定对象加锁,进入同步代码库前要获得给定对象。
synchronized的字节码指令
synchronized同步块使用了monitorenter和monitorexit指令实现同步,这两个指令,本质上都是对一个对象的监视器(monitor)进行获取,这个过程是排他的,也就是说同一时刻只能有一个线程获取到由synchronized所保护对象的监视器。
线程执行到monitorenter指令时,会尝试获取对象所对应的monitor所有权,也就是尝试获取对象的锁,而执行monitorexit,就是释放monitor的所有权。
synchronized的锁的原理
两个重要的概念:一个是对象头,另一个是monitor。
Java对象头
在Hotspot虚拟机中,对象在内存中的布局分为三块区域:对象头(Mark Word、Class Metadata Address)、实例数据和对齐填充;Java对象头是实现synchronized的锁对象的基础。一般而言,synchronized使用的锁对象是存储在Java对象头里。它是轻量级锁和偏向锁的关键。
Mark Word
Mark Word用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的
锁、偏向线程 ID、偏向时间戳等等。Java对象头一般占有两个机器码(在32位虚拟机中,1个机器码等于4字节,
也就是32bit)。
Class Metadata Address
类型指针,即是对象指向它的类的元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。
Array length
如果对象是一个Java数组,那在对象头中还必须有一块用于记录数组长度的数据。
Monitor
Monitor是一个同步工具,它内置于每一个Object对象中,相当于一个许可证。拿到许可证即可以进行操作,没有拿到则需要阻塞等待。
在hotspot虚拟机中,通过ObjectMonitor类来实现monitor。
synchronized锁的优化
jdk1.6以后对synchronized的锁进行了优化,引入了偏向锁、轻量级锁,锁的级别从低到高逐步升级:
无锁->偏向锁->轻量级锁->重量级锁
自旋锁与自适应自旋
线程的挂起和恢复会极大的影响开销。并且jdk官方人员发现,很多线程在等待锁的时候,在很短的一段时间就获得了锁,所以它们在线程等待的时候,并不需要把线程挂起,而是让他无目的的循环,一般设置10次。这样就避免了线程切换的开销,极大的提升了性能。
而适应性自旋,是赋予了自旋一种学习能力,它并不固定自旋10次一下。他可以根据它前面线程的自旋情况,从而调整它的自旋,甚至是不经过自旋而直接挂起。
锁消除
对不会存在线程安全的锁进行消除。
锁粗化
如果jvm检测到有一串零碎的操作都对同一个对象加锁,将会把锁粗化到整个操作外部,如循环体。
偏向锁
多数情况下,锁不仅不存在多线程竞争,而且总是由同一线程多次获得,为了让其获得锁的代价更低而引入了偏向锁。
当一个线程访问同步块并获取锁时,会在对象头和栈帧中的锁记录里存储锁偏向的线程ID,以后该线程在进入和退出同步块时不需要进行CAS操作来加锁和解锁,只需简单地测试一下对象头的Mark Word里是否存储着指向当前线程的偏向锁。
如果测试成功,表示线程已经获得了锁。
如果测试失败,则需要再测试一下Mark Word中偏向锁的标识是否设置成01(表示当前是偏向锁)。
如果没有设置,则使用CAS竞争锁。
如果设置了,则尝试使用CAS将对象头的偏向锁指向当前线程。
轻量级锁
引入轻量级锁的主要目的是在多线程竞争不激烈的情况下,通过CAS竞争锁,减少传统的重量级锁使用操作系统互斥量产生的性能消耗。
重量级锁
重量级锁通过对象内部的监视器(monitor)实现,其中monitor的本质是依赖于底层操作系统的Mutex Lock实现,操作系统实现线程之间的切换需要从用户态到内核态的切换,切换成本非常高。
锁升级
偏向锁升级轻量级锁:当一个对象持有偏向锁,一旦第二个线程访问这个对象,如果产生竞争,偏向锁升级为轻量级锁。
轻量级锁升级重量级锁:一般两个线程对于同一个锁的操作都会错开,或者说稍微等待一下(自旋),另一个线程就会释放锁。但是当自旋超过一定的次数,或者一个线程在持有锁,一个在自旋,又有第三个来访时,轻量级锁膨胀为重量级锁,重量级锁使除了拥有锁的线程以外的线程都阻塞,防止CPU空转。
wait和notify的原理
调用wait方法,首先会获取监视器锁,获得成功以后,会让当前线程进入等待状态进入等待队列并且释放锁。
当其他线程调用notify后,会选择从等待队列中唤醒任意一个线程,而执行完notify方法以后,并不会立马唤醒线程,原因是当前的线程仍然持有这把锁,处于等待状态的线程无法获得锁。必须要等到当前的线程执行完按monitorexit指令以后,也就是锁被释放以后,处于等待队列中的线程就可以开始竞争锁了。
wait和notify为什么需要在synchronized里面?
wait方法的语义有两个,一个是释放当前的对象锁、另一个是使得当前线程进入阻塞队列,而这些操作都和监视器是相关的,所以wait必须要获得一个监视器锁。
而对于notify来说也是一样,它是唤醒一个线程,既然要去唤醒,首先得知道它在哪里,所以就必须要找到这个对象获取到这个对象的锁,然后到这个对象的等待队列中去唤醒一个线程。
转载于:https://www.cnblogs.com/heqiyoujing/p/11144649.html
synchronize原理相关推荐
- 暴力突破 Java 并发 - synchronize 解析
一.前言 当存在多个线程操作共享数据时,需要保证同一时刻有且只有一个线程在操作共享数据,其他线程必须等到该线程处理完数据后再进行,这种方式有个高尚的名称叫互斥锁,即能达到互斥访问目的的锁,也就是说当一 ...
- 大厂Java岗面试心得记录
最近裸辞,面了几家大厂,offer率高达100% 哈哈,然后发现选公司也是一件难事. 废话不多说,分享一下,我遇到的面试题,大概有以下这些: JVM: 1.JVM有哪些区域? 2.堆和栈分别说说内部东 ...
- 应该是史上最全最新Java和Android面试题目(自己总结和收集的)
Android面试题目 Java 基础 int占用几个字节 讲一下常见编码方式? UTF-8编码下中文占几个字节 int和Interger的区别 int.char.long各占多少字节数 string ...
- Android最新面试实战总结
热文导读 | 点击标题阅读 金九银十跳槽季如何进阶找到合适满意的工作? Spring中的9种设计模式汇总 凛冬将至?对互联网行业人员流动性的一些看法(深度好文) 作者:骑小猪看流星 来源:http:/ ...
- 枪出惊龙,众“锁”周之
枪出惊龙,众"锁"周之 1.为什么要上锁?锁的意义是什么? 1 多线程访问共享数据,保证数据的安全 2 他会降低并发量,但是他能保证数据的安全 问题:秒杀本来是高并发的场景,你加锁 ...
- JAVA多线程之Synchronize 关键字原理
image 众所周知 Synchronize 关键字是解决并发问题常用解决方案,有以下三种使用方式: 同步普通方法,锁的是当前对象. 同步静态方法,锁的是当前 Class 对象. 同步块,锁的是 {} ...
- 大话synchronize底层原理
在每个对象中mark word中LockWord指向monitor的起始地址,也就是每个对象与一个monitor相关联.在monitor中有个Owner字段记录着拥有锁的线程.初始时为NULL表示当前 ...
- synchronize底层原理
1.对象内存布局 2.markword内容 3.锁状态图 4.轻量级锁 如果只有当前线程给对象加锁,则使用轻量级锁.(ps:没有其他线程和当前线程竞争,竞争就是两个线程同时给一个对象加锁) 加锁过程: ...
- 计算机共享原理,synchronize底层原理 游戏电脑问题解决分享!
sync 1 package com.paddx.test.concurrent; 2 3 public class SynchronizedDemo { 4 public void method() ...
最新文章
- Eclipse 官宣,干掉 VS Code !
- PHP 入门 - 7.Web技术
- 计算机专业英语第二版张强华翻译_计算机语言发展的三个阶段,机器语言、汇编语言与高级语言...
- mui toast自定义样式
- java 易错题_java错题集(1-3)
- 拓端tecdat|R语言用普通最小二乘OLS,广义相加模型GAM ,样条函数进行逻辑回归LOGISTIC分类
- sqlserver替换特殊字符
- 下载谷歌瓦片地图并拼接为高清大图
- 教你利用腾讯云cdn加速网站静态资源
- matlab的卡方临界值,Excel计算卡方分布,F分布
- matlab中单刀双掷开关,proteus 怎样找单刀双掷开关
- 我是80后程序员,我支持正版!
- 如何在国内快速访问Github
- Web程序中打开QQ、邮箱、阿里旺旺等
- Java数据可视化 (JavaFX, Apache ECharts)
- 全网通用Python点赞器(俗称刷分机器),想知道原理吗?看完本文你自己也能写个
- 发展科技到底有什么用,转NASA专家给一位修女的一封信
- 2020研究生数模竞赛思路
- python在西安好找工作吗_为什么我不建议你通过 Python 去找工作?
- 佟大为新任《非诚》嘉宾 极力反对异地恋
热门文章
- mysql 存储引擎接口_MySQL 的基础一(连接池, SQL接口, 查询解析器, 查询优化器, 存储引擎接口, 执行器,)...
- 有关EMMC、Nandflash、SSD、HDD的科普类说明
- head在linux命令中什么意思,linux系统中head命令使用说明
- bat php 监控网站,bat curl 发送http请求 监控网站
- 语句作用_3分钟短文:Laravel模型作用域,为你“节省”更多代码
- c语言试卷大全,C语言试题大全
- 日志分析系统分类有哪些_Java开发日志规范
- Linux 系统配置Java Idea Tomcat 全过程
- 数学--数论--HDU 2582 F(N) 暴力打表找规律
- 康美药业财务造假给股民造成的损失,股民该怎么办?