Synchronized关键字及锁的升级状态
① 对于synchronized锁的理解
- Synchronized锁的理解:执行System.out.println(*****)这段代码时,synchronized锁定了o这个对象,而不是锁定代码块,锁的信息记录在对象里;
简单理解:你要进屋子里,就要打开门,对象就是门,锁要加在门上,也就是对象上;
- 锁的信息是记录在对象头中的markword里面;
② JVM内置锁(Synchronized)的升级状态讲解
2.1 对象的状态有哪些?
- 无锁态 刚刚new出来的对象 001
- 偏向锁 101
- 轻量锁(自旋锁、无锁、自适应自旋) 00
- 重量锁 10
- GC标记
2.2 锁的升级状态讲解
Markword中记录的锁的信息
-
无锁态 --> 偏向锁
-
当第一个线程来使用时,先不用那么重量级的锁,就贴个标签(轻量锁);
-
主要针对没有出现竞争的情况;
-
-
偏向锁 --> 轻量锁
-
当有其他线程也来使用,造成竞争时,自动升级为轻量锁;
-
过程:撤销偏向锁,然后每个线程中的Lock Record用CAS的方式去抢锁;没抢到锁的线程就采用CAS机制自旋等待;
-
轻量锁执行在用户态,不需要经过内核态,效率高;
-
-
轻量锁 --> 重量锁
-
主要解决竞争较大时,某个线程占用CPU过久(占用锁过久)的问题,其他线程在一直自旋等待,等待过程会一直消耗 CPU;
-
重量锁需要经过内核态处理,效率低;
-
重量锁下有等待队列,将那些处于等待的线程加入到队列中,让其处于阻塞状态,这样等待的线程就不会消耗CPU。等待轮到哪个线程执行时,再将其出队列;
-
锁降级,不重要,就暂时认为不存在就好了。达到重量锁后,只能释放锁,然后再从无锁态开始循环上述过程。
2.3 其他概念
-
锁消除 - lock eliminate
-
锁粗化 - lock coarsening
③ Synchronized的底层实现 - 分层级讲解
- 1 java代码层级:代码中加了synchronized;
- 2 字节码层面:执行java代码,编译时在加锁的位置,执行前加了monitorenter(监视器)进入锁状态,整个synchronized代码执行完以后,加了moniterexit退出锁状态;
- 3 JVM层级: JVM在执行的过程中自动升级锁(锁升级);
- 4 更底层实现,CPU汇编层级:lock comxchg
来源:oschina
链接:https://my.oschina.net/u/4419899/blog/4346794