synchronized底层原理
并发叫号
static : 并发量大的时候会出现 : 跳号.重号.超过最大值
概念
互斥性 :即同一时间只允许一个线程持有某个对象锁
可见性 : 必须保证锁被释放之前,对共享变量所做的修改,对之后获得锁的对象是课件的
用法
修饰 : 静态方法 普通方法
修饰 : 代码块
monitor[监视器] : 每个对象都有一个monitor对象
- 某一线程占有这个对象的时候, 先看monitor的计数器是不是0 ,如果 是0则还没被进程占有,这个时候线程占有这个对象,并且对这对象的monitor +1 ,如果不为0 ,则表示被其他线程占有, 这个线程等待 . 当线程释放占有权的时候 monitor-1 .
- 同一线程可以对同一对象进行多次加锁 +1 [可重入锁]
原理分析
javap 反编译的命令
对代码块加synchronized 锁: monitorenter 和 monitorExit 配合使用
对方法进行加锁 [加标记]
1.6JDK 之前 重量锁
Java虚拟机对synchronized 进行了优化
对象头与monitor
一个对象实例包含 : 对象头.实例变量.填充数据
对象头 : 加锁的基础 (32bit )
实例变量 :
填充数据 :
无锁状态: 没有加锁
偏向锁 : 在对象第一次被某一线程占有的时候,将是否偏向锁置1 ,锁标记置 01 ,写入线程号,当其他线程访问的时候,竞争,失败 >>> 轻量级锁
很多次被第一次占有它的线程获取次数多 成功
CAS算法 : compare and swap
竞争不激烈的时候适用,
轻量级锁 : 线程有交替适用,互斥性不是很强,CAS失败,00
重量级锁 (等待时间长) : 强互斥,10 等待时间长
因为用户线程和核心线程(非常耗时)
自旋锁 : 竞争失败的时候,不是马上转换级别,而是执行几次空循环,有可能锁被释放
锁消除 : JIT编译的时候把不必要的锁去掉