当前位置:主页 > 查看内容

Sychronized中关于锁的一些理解

发布时间:2021-09-25 00:00| 位朋友查看

简介:jdk1.6中为了减少获取锁和得到锁带来的性能消耗引入了偏向锁和轻量级锁。再java1.6中锁有四种状态。 无锁 偏向锁 轻量级锁 重量级锁 偏向锁只适用于一个线程访问的情景 其实锁是不存在多线程竞争的且总是由同一线程多次获得为了让线程获得锁的代价更低。引入……

jdk1.6中为了减少获取锁和得到锁带来的性能消耗,引入了偏向锁和轻量级锁。再java1.6中,锁有四种状态。

  • 无锁
  • 偏向锁
  • 轻量级锁
  • 重量级锁
  • 在这里插入图片描述

偏向锁(只适用于一个线程访问的情景)

其实锁是不存在多线程竞争的,且总是由同一线程多次获得,为了让线程获得锁的代价更低。引入了偏向锁。当一个线程访问同步代码块并获取锁时,会在对象头和栈帧中锁记录中记录偏向锁的线程id。 当以后该线程再进入同步代码块的时候,只需要简单的测试对象头里面的Mark Word的存储结构是否存储着指向当前线程的偏向锁。如果,测试成功,那么久表示获得了锁。如果测试失败,那么就需要测试一下偏向锁的标识是否设置了1,如果是1则尝试使用CAS将对象头的偏向锁指向当前线程,如果不是1则使用CAS竞争锁。
偏向锁使用了竞争出现才释放锁的机制,当其他线程尝试晶振偏向锁时持有偏向锁的线程菜会释放锁。而且需要等待全局安全点。安全点指的是,在这个时间点上没有正在执行的字节码。撤销的时候先检查持有偏向锁的线程是否还活着,如果线程不处于活动状态,则将对象头设置为成无锁状态。如果线程仍然活着,拥有偏向锁的栈会被执行,遍历偏向对象的锁记录,栈中的锁记录和对象头的Mark Word要么重新偏向其他线程,要么恢复到无所或标记对象不适合作为偏向锁,最后唤醒。
在这里插入图片描述
轻量级锁
加锁:
线程在执行同步块之前,JVM会先在当前线程的栈桢中创建用于存储锁记录的空间,并将对象头中的Mark Word复制到锁记录中,官方称为Displaced Mark Word。然后线程尝试使用CAS将对象头中的Mark Word替换为指向锁记录的指针。如果成功,当前线程获得锁,如果失败,表示其他线程竞争锁,当前线程便尝试使用自旋来获取锁。
解锁:
轻量级解锁时,会使用原子的CAS操作将Displaced Mark Word替换回到对象头,如果成
功,则表示没有竞争发生。如果失败,表示当前锁存在竞争,锁就会膨胀成重量级锁。图2-2是
两个线程同时争夺锁,导致锁膨胀的流程图。在这里插入图片描述
偏向锁:加锁和解锁不需要额外的消耗,但是线程之间存在锁竞争,锁撤销的时候消耗要大。
轻量级锁:竞争的线程不会阻塞,提高了线程的响应速度。如果始终得不到锁,那么就会自旋消耗cpu。 目的是为了追求相应时间。
重量级锁:不会使用自旋,不消耗cpu。线程阻塞,响应慢,但是追求吞吐量。

参考java编程之美 ,记录本文是为了加深自己对并发的锁的印象

;原文链接:https://blog.csdn.net/qq_42674604/article/details/116061200
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!
上一篇:java并发编程之Lock锁 下一篇:没有了

推荐图文


随机推荐