• aaa


    synchronized底层实现以及优化


    轻量级锁:
    试想一下:如果当前有多个线程交替调用一个方法,且这些线程之间不存在竞争。有无必要在调用该方法前使用重量级锁独占它?由于不存在多线程
    竞争,对其加锁并没有实际意义。更何况重量级锁需要借助操作系统底层的互斥来实现,需要在用户态和核心态之间相互切换,会消耗
    许多系统资源。轻量级锁就是针对这种情况提出一种优化手段。

    如何获取锁
    释放锁
    何时升级为重量级锁

    偏向锁:
    试想下,在某段时间内,方法 fun() 只会被线程 ThreadA 调用。更甚者在相当长一段时间内只有 ThreadA 调用 fun(),你能感觉到它有多
    希望能直接进入同步方法执行吗!
    它不想借助 synchronized 这样的重量级锁来独占对象后才能执行 fun(),因为那简直是对系统资源的极大浪费...那么好,
    不借助 synchronized 关键字,用轻量级锁是不是可以呢?
    上面有提到轻量级锁在获取锁时,会触发多次CAS操作。但是只有 ThreadA 独占该方法啊,ThreadA 表示这些CAS操作它也不想干!能不能有个标识能
    告诉他当前锁的占有者是谁?如果发现这个锁的占有着就是它自己,那直接访问就好了不是吗?

    实际偏向锁也是使用该思路来实现的。在MarkWord中可以记录当前锁占用线程的线程ID用来标识锁的占有者;同时还有是否为偏向锁标识等。

    如何获取偏向锁?
    1、获取对象头MarkWord,是否为偏向锁
    2、如果是偏向锁,判断当前MarkWord中保存的线程ID是否为当前线程;如果是直接执行同步代码;如果不是执行3
    3、通过CAS将MarkWord中的线程ID更新为当前线程ID,若成功执行同步代码
    4、如果CAS操作失败,表示当前存在多线程竞争的情况,当线程到达全局安全点的时候,占有偏向锁的线程将被挂起,同时升级为轻量级锁

    释放锁
    偏向锁很特殊,它采用了一种有线程竞争才会释放锁的机制。换句话来说,如果当前场景只有线程A在运行,且没有多线程竞争,那么正在运行的线程A
    将一直持有该偏向锁。而偏向锁无需进行多次 CAS 操作的实现相比轻量级锁,在一定程度上节约提高了系统效率。
    偏向锁的释放过程:
    1、偏向锁的释放必须等到全局安全点(safepoint通常出现在循环结束后,方法返回前等地方)
    2、暂停当前拥有偏向锁的线程,判断偏向锁是否处于锁定状态
    3、如果偏向锁处于非锁定状态,将其恢复到无锁状态(01);如果处于锁定状态,此时会升级为轻量级锁

    小结:偏向锁可以提高只有单线程调用的系统性能,但是如果当前场景经常存在多线程相互竞争的情况,那么使用偏向锁实际上也没有意义了。

  • 相关阅读:
    SQL——索引
    const 与 readonly知多少
    ASP.NET MVC 4 RC的JS/CSS打包压缩功能
    学习IIS & MVC的运行原理
    IIS中使用ASP.NET MVC的经验总结
    cookie 和session 的区别详解
    SQL之经典语句
    SQL存储过程,使用事务(try catch),游标
    深入理解SQL的四种连接-左外连接、右外连接、内连接、全连接
    Sql效能优化总结(续)- sql语句优化篇
  • 原文地址:https://www.cnblogs.com/cfyrwang/p/8493808.html
Copyright © 2020-2023  润新知