A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 大蓝鲸小蟀锅 于 2020-3-13 23:05 编辑

JAVA锁优化




锁一共有4种状态:无锁状态偏向锁状态轻量级锁状态重量级锁状态





一、偏向锁


    大多数情况下,锁不仅不存在多线程竞争,而且总是由同一线程多次获得,为了让线程获得锁的代价更低而引入了偏向锁。

偏向锁使用了一种等到竞争出现才释放锁的机制,所以当其他线程尝试竞争偏向锁时,持有偏向锁的线程才会释放锁。



    那么什么时候使用偏向锁呢?在这样的场景:如果始终只有一个线程在执行同步块,在它没有执行完释放锁之前,没有其它线程去执行同步块,在锁无竞争的情况下使用,一旦有了竞争就升级为轻量级锁,升级为轻量级锁的时候需要撤销偏向锁,撤销偏向锁的时候会导致线程暂停操作。



二、轻量级锁



如果偏向锁失败,那么系统会进行轻量级锁的操作,使用CAS操作来尝试加锁。如果轻量级锁失败,才调用系统级别的重量级锁来加锁。



轻量级锁加锁:

线程在执行同步块之前,JVM会创建存储锁记录的空间。然后线程尝试使用CAS将对象头中的Mark Word替换为指向锁记录的指针,成功,当前线程获得锁。如果失败,表示其他线程竞争锁,当前线程便尝试使用自旋来获取锁。



轻量级锁解锁:

会使用原子的CAS操作将Displaced Mark Word替换回到对象头,如果成功,则表示没有竞争发生。如果失败,表示当前锁存在竞争,锁就会膨胀成重量级锁。




自旋锁



自旋:当线程申请锁时,锁被占用,就让线程执行循环,看看持有锁的线程是否会释放。如还没获得锁,进入同步阻塞状态。

自适应自旋: 自适应意味着时间不固定,而是由前一次的自旋时间和锁拥有者状态决定。如果在同一个锁对象上,自旋等待刚刚成功,并持锁线程在运行,jvm就认为自旋是再次成功的。如果自旋很少成功过,尝试获取这个锁将阻塞线程。







0 个回复

您需要登录后才可以回帖 登录 | 加入黑马