有偏见的锁定设计决策
Posted
技术标签:
【中文标题】有偏见的锁定设计决策【英文标题】:Biased locking design decision 【发布时间】:2017-11-27 21:19:08 【问题描述】:我正在尝试了解偏向锁定背后的基本原理并将其设为默认值。自读this blog post,即:
“由于大多数对象在其生命周期内最多被一个线程锁定,因此我们允许该线程将对象偏向自身”
我很困惑...为什么有人会设计一组同步的方法,只能由一个线程访问?在大多数情况下,人们专门为多线程用例设计某些构建块,而不是单线程用例。在这种情况下,没有偏差的线程的每次锁获取都是以安全点为代价的,这是一个巨大的开销!有人可以帮我理解这张照片中我缺少什么吗?
【问题讨论】:
几个线程安全对象(尤其是在 Java 的早期阶段)大部分时间都用于单线程用例(例如,Vector、Hashtable、StringBuffer)。关于第二个问题,论文说:“但是,如果另一个线程试图获取一个偏置对象,我们需要撤销原始线程的偏置。(此时我们可以重新偏置对象或简单地恢复到正常锁定)对象生命周期的剩余时间”。 查看类加载,例如。当然,这必须以线程安全的方式实现。尽管如此,大多数情况下,几乎所有的类都是在应用程序启动期间由主线程加载的,或者至少有大量类是在另一个线程第一次获取类加载锁之前加载的。 【参考方案1】:原因可能是有相当数量的库和类被设计为线程安全的,但在这种情况之外仍然有用。对于早于 Collections 框架的许多类来说尤其如此。 Vector
及其子类就是一个很好的例子。如果您还考虑到大多数 Java 程序不是多线程的,那么在大多数情况下,使用偏向锁定方案是一种整体改进,对于使用此类类非常普遍的遗留代码来说尤其如此。
【讨论】:
【参考方案2】:您在某种程度上是正确的,但在某些情况下这是需要的,正如 Holger 在他的评论中非常正确地指出的那样。有所谓的宽限期,就是完全不尝试偏向锁定,所以这种情况不会一直发生。我最后一次记得查看代码时,它是5 seconds
。为了证明这一点,您需要一个可以检查 Java 对象标头的库(我想到了jol
),因为偏向锁定在mark word
中。因此,只有在 5 秒后,之前持有锁的对象才会偏向朝向同一个锁。
编辑
我想为此编写一个测试,但似乎已经有了一个!这里is the link for it
【讨论】:
以上是关于有偏见的锁定设计决策的主要内容,如果未能解决你的问题,请参考以下文章