Java中的每一个对象都有一个monitor与之关联,当且一个monitor被持有后,对象将处于锁定状态。
一、操作系统内部的互斥锁
1、JDK6之前:Monitor的实现完全依靠操作系统内部的互斥锁。需要进行用户态到内核态的切换。
synchronized代码块是由monitorente/monitorexit(这两个字节码都有一个reference类型的参数来指明要锁定和解锁的对象)指令实现的,Monitor对象是同步的基本实现。
二、偏斜锁、轻量级锁、重量级锁
JDK1.6后,JVM实现的锁一共有4种状态,级别从低到高分别是无锁、偏向锁、轻量级锁、重量级锁,会随着竞争情况逐渐升级。
偏斜锁:当没有竞争出现时,利用CAS操作在对象头Mark Word部分设置线程ID,表示这个对象偏向于某个线程。
轻量级锁:如果有另外的线程试图锁定已经被偏斜过的对象,则依赖CAS操作Mark Word来试图获取锁,成功则使用轻量级锁,否则就升级为重量级锁。
二、Java对象头锁标识位
synchronized用的锁是存在Java对象头里的。普通对象使用两个字宽度存储对象头,数组对象使用3个字宽度。Java对象头的Mark Word里默认存储对象的HashCode、分代年龄、和锁标记位。Mark Word为1字宽,即32bit或64bit(32位JVM、64位JVM)。