13.3 锁优化

1. 自旋锁与自适应自旋。共享数据的锁定只会持续短时间,通过自旋看看持有锁的线程是否会很快释放。1.6之后加入自适应自旋,根据前一次在同一个锁上的自旋时间及拥有者状态而定。

2. 锁消除。通过逃逸分析发现无法被其他线程访问到,那么会消除该锁。

3. 锁粗化。零碎的加锁,会拓展其加锁同步的范围。

4. 轻量级锁。轻量级锁是基于大部分锁不被竞争的情况设计的,这样可以避免互斥锁的开销,如果存在锁竞争,那么除了互斥量的开销,还会额外有CAS的开销,那么这种情况下,轻量级锁会更慢。

    加锁过程。对象头部信息中存在Mark Word中,首先通过CAS尝试更新对象的MarkWord为当前栈帧,如果成功则将该对象的锁定位置成“00”,如果更新失败,检查对象的MarkWord是否指向当前的栈帧,如果是则可重入,执行代码即可,如果不是,则说明该对象已经被其他对象抢占。当超过两个线程争用锁的时候,轻量级锁将会膨胀为重量级锁,MarkWord的锁标志值将会变成“10”,存储的地址也会指向重量级锁(互斥量),后面等待锁的线程也将进入阻塞状态。 

    解锁过程。同样通过CAS实现,失败时释放锁的同时唤起挂起的线程。

5. 偏向锁。可以提高有同步但无竞争的程序性能,对于大多数都是被不同进程访问的情况,反而是多余的。目的是消除无竞争情况下的同步。如果说轻量级锁是使用CAS去消除同步使用的互斥量,那么偏向锁是在无竞争情况下消除整个同步,CAS都不执行。

    锁对象第一次被获取的时候,虚拟机把对象头的标识位设为“01”,即偏向模式,同时把线程的ID信息记录在MarKWord中,如果CAS成功,那么持有偏向锁的线程每次进入锁的相关同步块时,虚拟机不再进行任何同步操作。但另外一个线程尝试获取时,偏向模式结束,根据对象的状态退回到未锁定或轻量级锁模式。


你可能感兴趣的:(13.3 锁优化)