"ReentrantLock"和"synchronized"之间在CPU级别上的实现有何不同?或者他们使用相同的"CAS"方法?
Coo*_*tri 10
如果我们谈论ReentrantLockvs synchronized(也称为"内部锁定"),那么查看Lock文档是个好主意:
所有Lock实现必须强制执行内置监视器锁提供的相同内存同步语义:
- 成功的锁定操作就像成功的monitorEnter操作一样
- 成功的解锁操作就像成功的monitorExit操作一样
所以一般认为这synchronized只是一种易于使用且简洁的锁定方法.通过使用ReentrantLock更多代码编写代码,您可以实现完全相同的同步效果(但它提供了更多选项和灵活性).
前段时间ReentrantLock在某些条件下(例如高争用)更快,但现在Java使用不同的优化技术(如锁定粗化和自适应锁定)来使程序员几乎看不到许多典型场景中的性能差异.
在低争用情况下(例如偏置锁定),优化内在锁定也做得很好.Java平台的作者喜欢synchronized关键字和内在锁定方法,他们希望程序员不要害怕使用这个方便的工具(并防止可能的错误).这就是为什么synchronized优化和"同步缓慢"神话破坏对于Sun和Oracle而言是如此重要.
问题的"CPU部分":
synchronized使用内置于JVM和MONITORENTER/ 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
ReentrantLock类实现了Lock,具有与synchronized相同的并发和内存语义,但还添加了锁轮询、定时锁等待和可中断锁等待等功能。此外,它在激烈竞争的情况下提供了更好的性能。
以上答案摘自Brian Goetz 的文章。您应该阅读整篇文章。它帮助我理解了两者的差异。
| 归档时间: |
|
| 查看次数: |
1774 次 |
| 最近记录: |