ps:jdk1.6之前加synchronized直接就是重量级锁,从jdk1.6开始对锁进行优化,根据同步块竞争的激烈程度来实现锁的升级。
对象的存储
对象头、实例数据、对齐填充
对象头结构
- 对象标记(markOop _mark也就我们后面提到的Mark word)
- 元数据
虚拟机对象头源码
虚拟机markOop部分源码
Mark Word的内容
锁的类型
- 无锁
- 偏向锁
- 轻量级锁
- 重量级锁
无锁
当使用了同步块但是没有线程去访问对象头锁状态为无锁。
如何获取偏向锁
- 获取目标对象的对象头
- 根据锁标识进行判断
CAS操作是为了保证线程安全
如何获取轻量级锁
- 在当前线程的栈帧里面创建一个存储LockRecord的空间
- 对象头中的Mark Word复制到锁记录,Displaced Mark Word
- CAS,将线程栈帧中锁记录地址CAS到对象头
锁的释放则是把线程栈帧的锁记录替换到对象头里。
如何获取重量级锁
当竞争激烈程度达到某种水平,对象头锁的状态变成重量级锁。在轻量级锁中频繁的cas操作会消耗很多cpu,当升级为重量级锁后只需要让没有获得锁的线程挂起然后重新竞争。