• 偏向锁、轻量级锁、重量级锁、synchronized的原理


    synchronized用的锁是存在Java对象头里的

    Java对象头里的Mark Word里默认存储对象的HashCode、分代年龄和锁标记位。、

    32位JVM 的Mark Word的默认存储结构

    在运行期间,Mark Word里存储的数据会随着锁标志位的变化而变化

    64位JVM 的Mark Word的默认存储结构

    锁的升级与对比

    偏向锁

    偏向锁的引入:为了让线程获得锁的代价更低。节约了加锁的流程

    当一个线程访问同步块并获取锁时,会在对象头和栈帧中的锁记录里存储锁偏向的线程ID,以后该线程在进入和退出 同步块时不需要进行CAS操作来加锁和解锁,只需简单地测试一下对象头的Mark Word里是否存储着指向当前线程的偏向锁。

    偏向锁的撤销 :等到竞争出现才释放锁,当其他线程尝试竞争偏向锁时,持有偏向锁的线程才会释放锁。简单来说就是两个线程,一个有偏向锁,另一个来和他抢,只有这样,才会释放锁。只有等全局安全点的时候,才会撤销。

    具体撤销过程:它会首先暂停拥有偏向锁的线程,然后检查持有偏向锁的线程是否活着, 如果线程不处于活动状态,则将对象头设置成无锁状态;如果线程仍然活着,拥有偏向锁的栈 会被执行,遍历偏向对象的锁记录,栈中的锁记录和对象头的Mark Word要么重新偏向于其他 线程,要么恢复到无锁或者标记对象不适合作为偏向锁,最后唤醒暂停的线程。图2-1中的线

    程1演示了偏向锁初始化的流程

    关闭偏向锁: 在java6,java7中默认启用可以通过JVM参数关闭偏向锁:-XX:- UseBiasedLocking=false,那么程序默认会进入轻量级锁状态

    轻量级锁:

    (1)轻量级锁加锁 线程在执行同步块之前,JVM会先在当前线程的栈桢中创建用于存储锁记录的空间,并 将对象头中的Mark Word复制到锁记录中,官方称为Displaced Mark Word。然后线程尝试使用 CAS将对象头中的Mark Word替换为指向锁记录的指针。如果成功,当前线程获得锁,如果失败,表示其他线程竞争锁,当前线程便尝试使用自旋来获取锁。

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

    自旋锁的好处是在一个锁释放后可以最快速度的再给他加一个锁。坏处是比如三个自旋锁,一个抢到了资源并加锁,而另外两个自旋就会被浪费。如果有好多线程自选,那么一个成功,其他全都浪费,对cpu浪费很大。所以说 线程多的时候,我们就把轻量级锁就会变成重量级锁。重量级锁竞争失败的之后就会进入阻塞队列,就不会浪费cpu。当一个线程执行完会通知阻塞队列,再换一个线程执行。

    轻量级锁与重量级锁的区别:轻量级锁加锁快,重量级锁一般不会对cpu造成浪费。

    三个锁应用场景:无并发用偏向锁,低并发用轻量级锁,高并发用重量级锁

    偏向锁在哪配置:对象头的Mark Word里

    自旋锁要自旋多少次才能生成重量级锁:自旋超过10次生成重量级

  • 相关阅读:
    win11 vmware 安装Ubuntu 连接xshell
    SpringBoot 学习(四)数据库整合
    [NOI2019]斗主地
    [代码实战和详解]VGG16
    u盘就能用:RadiAnt DICOM Viewer CD/DVD 2023.1
    SQLServer重建所有索引
    Python&SQL应用随笔4——PySpark创建SQL临时表
    数据库总结之高级篇
    CSS 的盒子Day03(2)
    QT for andriod
  • 原文地址:https://blog.csdn.net/m0_61983575/article/details/127036862