轻量级锁

  1. 轻量级锁加锁
    线程在执行同步块之前,JVM 会先在当前线程的栈帧中创建用于存储锁记录的空间,并将对象头中的 Mark Word 复制到锁记录中,官方称为 Displaced Mark Word。然后线程尝试使用 CAS 将对象头中的 Mark Word 替换为指向锁记录的指针。如果成功,当前线程获得锁,如果失败,表示其他线程竞争锁,当前线程便尝试使用自旋来获取锁。
  2. 轻量级锁解锁
    轻量级解锁时,会使用原子的 CAS 操作将 Displaced Mark Word 替换回对象头,如果成功,则表示没有竞争发生。如果失败,表示当前锁存在竞争,锁就会膨胀成重量级锁。下乳是两个线程同时竞争锁,导致锁膨胀的流程图。


    轻量级锁_第1张图片
    2.png

    因为自旋会消耗 CPU,为了避免无用的自旋(比如获得锁的线程被阻塞住了),一旦线程升级成重量级锁,就不会再恢复到轻量级锁状态。当锁处于这个状态下,其他线程尝试获取锁,都会被阻塞住,当持有锁的线程释放锁之后会唤醒这些线程,被唤醒的线程会进行新一轮的夺锁之争。

  3. 锁的优缺点对比
优点 缺点 使用场景
偏向锁 加锁和解锁不需要额外的消耗,和执行非同步方法相比仅存在纳秒级的差距 如果线程间存在锁竞争,会带来额外的锁撤销的消耗 适用于只有一个线程访问同步块场景
轻量级锁 竞争的线程不会阻塞,提高了线程的相应速度 如果始终得不到锁竞争的线程,使用自旋会消耗CPU 追求相应时间,同步块执行的速度非常快
重量级锁 线程竞争不使用自旋,不会消耗CPU 线程阻塞,响应时间缓慢 追求吞吐量,同步块执行时间较长。

你可能感兴趣的:(轻量级锁)