synchronized 锁的升级过程

2 阅读2分钟

synchronized关键字是一种常用的线程同步机制,它不仅提供了互斥访问的功能,还具备锁升级的特性

在jdk1.5版本,锁的状态只有两种状态:“无锁状态”和“重量级锁状态”,jdk1.6版本后,对synchronized锁进行了优化,新加了“偏向锁”和“轻量级锁”,所以锁就有了4种状态。

java对象的内存布局里面的对象Markword的头信息

偏向锁 对象头中的线程ID设置为当前线程ID,后续当前线程再次访问这个共享资源时会根据偏向锁标识跟线程ID进行比对是否相同,比对成功则直接获取到锁进入临界区域 这是synchronized锁的可重入功能。

轻量级锁 当多个线程同时申请共享资源锁的访问时就产生了竞争,JVM会先尝试使用轻量级锁,以CAS方式来获取锁(一般就是自旋加锁,不阻塞线程采用循环等待的方式),成功则获取到锁,状态为轻量级锁,失败(达到一定的自旋次数还未成功)则锁升级到重量级锁。

如果共享资源锁已经被某个线程持有,此时是偏向锁状态,未释放锁前,再有其他线程来竞争时,则会升级到重量级锁,另外轻量级锁状态多线程竞争锁时,也会升级到重量级锁。底层是通过操作系统的mutex lock来实现的,每个对象指向一个monitor对象,这个monitor对象在堆中与锁是关联的,通过monitorenter指令插入到同步代码块在编译后的开始位置,monitorexit指令插入到同步代码块的结束处和异常处,这两个指令配对出现。