本文共 764 字,大约阅读时间需要 2 分钟。
锁
-
对于普通同步方法,锁是当前实例对象
-
对于静态同步方法,锁是当前class类对象
-
对于同步方法块,锁是括号内对象。
JVM基于进入和退出Monitor对象来实现方法和代码块同步。每个java对象都有一个Monitor与之对应。代码块同步是用monitorenter和monitorexit关键字实现。monitor的本质是依赖于底层操作系统的Mutex Lock实现。
synchronized用的锁是在Java对象头里的。如果对象是数组类型,则虚拟机用3个字宽存储对象头。如果对象是非数组类型,则用2个字宽存储对象头。在32位虚拟机中,1字宽=4字节(32bit)
对象头信息
长度 | 内容 | 说明 |
32/64bit | Mark word | 存储对象的HashCode或锁信息 |
同上 | Class Metadata Adress | 存储到对象类型数据的指针 |
32bit | Array length | 数组长度(如果对象是数组) |
mark word在运行期间会随着锁标志位变化而变化。(锁升级)
锁升级
JSE1.6做的优化
1.6中锁一共有4种状态:
-
无锁
-
偏向锁(自旋)
-
轻量级锁(自旋)
-
重量级锁
无锁
无竞争就无锁
偏向锁(可重入锁)
偏向锁的markWord记录的是持有锁的线程id
出现竞争的时候用CAS来获取锁。出现竞争就做偏向锁撤销逻辑,如果做撤销操作时,有线程持有偏向锁,则偏向锁升级为轻量级锁,将Mark word信息修改为轻量级锁,并copy到原偏向锁线程中。
轻量级锁
CAS操作将对象头的Mark word中锁记录指针指向当前线程锁记录。说明哪个线程持有锁。
CAS操作失败达到一定次数之后(10?),升级为重量锁,等待唤醒。
重量级锁
mark word指向Monitor对象的指针,互斥锁,阻塞没有竞争到锁的线程
转载地址:https://blog.csdn.net/xxxxssss12/article/details/105306744 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!