java - ReentrantLock 与 CPU 级别同步?

标签 java concurrency

'ReentrantLock' 和 'synchronized' 在 CPU 级别上的实现方式有区别吗? 还是他们使用相同的“CAS”方法?

最佳答案

如果我们谈论的是 ReentrantLocksynchronized(也称为“内部锁”),那么最好看看 Lock documentation :

All Lock implementations must enforce the same memory synchronization semantics as provided by the built-in monitor lock:

  • A successful lock operation acts like a successful monitorEnter action
  • A successful unlock operation acts like a successful monitorExit action

所以一般认为synchronized只是一种易于使用且简洁的锁定方法。您可以通过使用 ReentrantLock 编写更多代码(但它提供了更多选项和灵 active )来实现完全相同的同步效果。

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

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

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

ReentrantLock实现基于AbstractQueuedSynchronizer,纯Java编码(使用Java 5引入的CAS指令和线程调度),跨平台更稳定,提供更大的灵 active ,并尝试使用快速 CAS 方法每次获取锁(如果失败则使用操作系统级别的锁)。

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

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

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

关于java - ReentrantLock 与 CPU 级别同步?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36371149/

相关文章:

java - Eclipse RCP 更改启动画面的任务图标

java - Java 1.7 中 SimpleDateFormat 的行为变化?

java - 带有 StringEntity 的 HttpPost 具有特殊字符,如 ®,看到 ¿½` 而不是 ®

java - 从 Java 并发迁移到 Scala 并发

.net - .NET如何利用IO线程或IO完成端口?

multithreading - 这是Go中的惯用工作线程池吗?

haskell - `forkIO` 和 `putMVar` : what's going on under the hood?

java - SwingWorker doInBackground() 不起作用

java - 处理 Excel 文件

java - Android TextView.setText() 在按钮 onClickListener 中不执行任何操作