synchronize锁机制
-
jdk1.6做了哪些升级和优化?
- 适应自旋锁:为了减少线程状态改变带来的消耗 不停地执行当前线程
- 锁消除:不可能存在共享数据竞争的锁进行消除
- 锁粗化:将连续的加锁 精简到只加一次锁
- 轻量级锁:无竞争条件下 通过CAS消除同步互斥
- 偏向锁:无竞争条件下 消除整个同步互斥,连CAS都不操作
-
锁的使用机制
-
加入有这样一个同步代码块,存在 Thread#1、Thread#2 等 多个线程
情况一:只有 Thread#1 会进入临界区;
情况二:Thread#1 和 Thread#2 交替进入临界区,竞争不激 烈;
情况三:Thread#1/Thread#2/Thread3… 同时进入临界区, 竞争激烈
- 偏向锁:
- 此时当 Thread#1 进入临界区时,JVM 会将 lockObject 的 对象头 Mark Word 的锁标志位设为“01”,同时会用 CAS 操作把 Thread#1 的线程 ID 记录到 Mark Word 中,此时进 入偏向模式。所谓“偏向”,指的是这个锁会偏向于 Thread#1, 若接下来没有其他线程进入临界区,则 Thread#1 再出入 临界区无需再执行任何同步操作。也就是说,若只有 Thread#1 会进入临界区,实际上只有 Thread#1 初次进入 临界区时需要执行 CAS 操作,以后再出入临界区都不会有 同步操作带来的开销
- 轻量级锁:
- 偏向锁的场景太过于理想化,更多的时候是 Thread#2 也 会尝试进入临界区, 如果 Thread#2 也进入临界区但是 Thread#1 还没有执行完同步代码块时,会暂停 Thread#1 并且升级到轻量级锁。Thread#2 通过自旋再次尝试以轻量 级锁的方式来获取锁
- 重量级锁:
- 如果 Thread#1 和 Thread#2 正常交替执行,那么轻量级锁 基本能够满足锁的需求。但是如果 Thread#1 和 Thread#2 同时进入临界区,那么轻量级锁就会膨胀为重量级锁,意 味着 Thread#1 线程获得了重量级锁的情况下,Thread#2 就会被阻塞
- 偏向锁:
-
-
锁的四种状态:随着竞争的激烈而逐渐升级,可以升级不可降级策略
- 无锁状态:此时进入临界区无竞争
- 偏向锁:只有一个线程进入临界区
- 轻量级锁:多个线程交替进入临界区,竞争不激 烈
- 重量级锁:多个线程同时进入临界区,竞争激烈