首先,先来说一下轻量级锁的应用场景,当一个锁被多个线程访问,但是多个线程访问的时间是错开的(也就是不存在竞争现象)的时候,我们可以使用轻量级锁来进行优化。
轻量级锁的加锁过程比较简单。首先,当一个线程访问同步块之前,JVM会在该线程的栈帧中开辟一块存储锁的记录的空间。该线程会将锁的Markword复制到锁记录中。然后该线程尝试使用CAS操作将对象头的Markword替换为指向锁记录的指针。如果替换成功,表示加锁成功;如果替换失败,表示有其他线程在竞争该锁,那么当前线程会尝试使用自旋来获得该锁。
轻量级锁的解锁过程也是比较简单的。首先,线程会尝试使用CAS操作将DisplayedMarkWord替换回对象头。如果替换成功,说明没有线程在竞争该锁,表示解锁成功。如果替换失败,则表示有其他线程在竞争该锁,那么该锁会膨胀为重量级锁。
接下来我使用图示的方法来说明轻量级锁的加锁和锁膨胀的过程。