ReentrantLock与CPU级别同步?

“ReentrantLock”和“synchronized”之间在CPU级别上的实现方式有何不同? 或者他们使用相同的“CAS”方法?

如果我们谈论ReentrantLock vs synchronized (也称为“内部锁定”),那么查看Lock文档是个好主意:

所有Lock实现必须强制执行内置监视器锁提供的相同内存同步语义:

  • 成功的锁定操作就像成功的monitorEnter操作一样
  • 成功的解锁操作就像一个成功的monitorExit操作

因此,通常认为synchronized是一种易于使用且简洁的锁定方法。 通过使用ReentrantLock编写带有更多代码的代码,您可以实现完全相同的同步效果(但它提供了更多选项和灵活性)。

前段时间ReentrantLock在某些条件下更快(例如高争用),但现在Java使用不同的优化技术(如锁定粗化和自适应锁定)来使程序员几乎看不到许多典型场景中的性能差异。

在低争用情况下(例如偏置锁定),优化内在锁定也做得很好。 Java平台的作者喜欢使用synchronized关键字和内部锁定方法,他们希望程序员不要害怕使用这个方便的工具(并防止可能的错误)。 这就是为什么synchronized优化和“同步缓慢”神话破坏对Sun和Oracle来说是如此重要。

问题的“CPU部分”: synchronized使用内置于JVMMONITORENTER / MONITOREXIT字节码指令中的锁定机制。 因此,底层实现是特定于JVM的(这就是它被称为内部锁定的原因)和AFAIK 通常 (可能会发生变化)使用一种相当保守的策略:一旦锁定在锁定获取后线程冲突“膨胀”, synchronized开始使用OS基于锁定(“脂肪锁定”)而不是快速CAS(“瘦锁定”)并且不喜欢很快再次使用CAS(即使争用已经消失)。

ReentrantLock实现基于AbstractQueuedSynchronizer并使用纯Java进行编码(使用CAS指令和线程解析,它引入了Java 5),因此它在各个平台上更稳定,提供更大的灵活性并尝试使用快速CAS附件来获取每次锁定(如果失败则执行OS级锁定)。

因此,这些锁实现在性能方面的主要区别是锁获取策略(在特定的JVM实现或情况下可能不存在)。

并且没有一般的答案,锁定更好+ 它是在时间和平台期间改变的主题 。 您应该查看具体问题及其性质,以选择最合适的解决方案(通常在Java中)

PS:你很好奇,我强烈建议你看看HotSpot来源更深入(并找出特定平台版本的确切实现)。 这可能真的有帮助。 起点在这里: http : //hg.openjdk.java.net/jdk8/jdk8/hotspot/file/87ee5ee27509/src/share/vm/runtime/synchronizer.cpp

实现Lock的ReentrantLock类具有与synchronized相同的并发和内存语义,但还添加了锁定轮询,定时锁等待和可中断锁等待等function。 此外,它在竞争激烈的情况下提供了更好的性能。

资源

以上答案摘自Brian Goetz的文章 。 你应该阅读整篇文章。 它帮助我理解了两者的差异。