• 偏向锁、轻量级锁、重量级锁、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次生成重量级

  • 相关阅读:
    关于Vue+webpack使用unocss编写CSS,打包后CSS没加前缀
    简单了解ARP协议
    javaweb高校物资采购进销存管理系统ssm框架
    spring boot @Configuration和@Componment的区别
    docker kafka
    喜报 | 热烈祝贺思腾合力成功挂牌天津OTC专精特新板
    [算法周训 2]字符串训练1
    二、进程管理(四)经典同步互斥问题
    leetcode做题笔记2760. 最长奇偶子数组
    第 365 场 LeetCode 周赛题解
  • 原文地址:https://blog.csdn.net/m0_61983575/article/details/127036862