Synchronized锁种类及升级步骤
Synchronized锁种类及升级步骤
Synchronized锁种类及升级步骤:
(注意:读二进制时,每一行从右往左读,每一组二进制从左往右读)
①无锁:
②偏向锁:
单线程竞争,当线程A第一次竞争到锁时,通过修改MarkWord中的偏向线程ID、偏向模式。如果不存在其他线程竞争,那么持有偏向锁的线程将永远不需要进行同步。
主要作用: (偏向锁通过避免用户态到内核态的切换(即不向操作系统申请锁),显著提升了单线程重复获取锁的性能)
- 当一段同步代码一直被同一个线程多次访问,由于只有一个线程那么该线程在后续访问时便会自动获得锁
- 同一个老顾客来访,直接老规矩行方便
理论落地:
技术实现:
偏向锁的撤销:
- 当有另外一个线程逐步来竞争锁的时候,就不能再使用偏向锁了,要升级为轻量级锁,使用的是等到竞争出现才释放锁的机制
- 竞争线程尝试CAS更新对象头失败,会等到全局安全点(此时不会执行任何代码)撤销偏向锁,同时检查持有偏向锁的线程是否还在执行:
-
- 第一个线程正在执行Synchronized方法(处于同步块),它还没有执行完,其他线程来抢夺,该偏向锁会被取消掉并出现锁升级,此时轻量级锁由原来持有偏向锁的线程持有,继续执行同步代码块,而正在竞争的线程会自动进入自旋等待获得该轻量级锁
- 第一个线程执行完Synchronized(退出同步块),则将对象头设置为无所状态并撤销偏向锁,重新偏向。
③轻量级锁:
概念:多线程竞争,但是任意时候最多只有一个线程竞争,即不存在锁竞争太激烈的情况,也就没有线程阻塞
主要作用:有线程来参与锁的竞争,但是获取锁的冲突时间极短---------->本质是自旋锁CAS
轻量锁的获取:
(即CAS时线程A还在使用锁,就将锁升级为轻量级别)
轻量锁的加锁:
轻量锁的释放(轻量级锁每次退出同步块都需要释放锁):
加锁时的自旋程度和次数(Java8 之后是自适应自旋锁------意味着自旋的次数不是固定不变的):
- 线程如果自旋成功了,那下次自旋的最大次数会增加,因为JVM认为既然上次成功了,那么这一次也大概率会成功
- 如果很少会自旋成功,那么下次会减少自旋的次数 甚至不自旋,避免CPU空转
④重量级锁:

浙公网安备 33010602011771号