我有一些类似于 map 的存储空间。我一直在为 get
和 put
方法使用 synchronized(this)
。由于此存储主要用于读取,我想到了使用 ReentrantReadWriteLock
以获得更好的性能 - 仅在 put
上锁定。
我希望在查找时有更好的性能(因为存储内容没有改变)。然而,我的 JMH 测试显示相反的结果:
.benchmarkClassMap3ClassLookup thrpt 20 460.152 7.417 ops/ms
.benchmarkClassMapClassLookup thrpt 20 1196.085 23.635 ops/ms
第一行是使用ReentrantReadWriteLock
的代码。第二行是原代码,synchronized
。编辑:测试使用 2 个线程运行。
其他人是否对 ReentrantReadWriteLock
进行了基准测试?结果不应该不同吗?还是只有在多线程环境下才会出现正结果?
相关:this .
最佳答案
您肯定需要多个线程才能看到好处,因为 ReentrantReadWriteLock比简单的 synchronized
更复杂。在 synchronized
的情况下,如果 JVM 发现只有一个线程,它可能会优化并一起删除同步。但这里也有来自 ReentrantReadWriteLock javadoc 的引用:
ReentrantReadWriteLocks can be used to improve concurrency in some uses of some kinds of Collections. This is typically worthwhile only when the collections are expected to be large, accessed by more reader threads than writer threads, and entail operations with overhead that outweighs synchronization overhead.
如果您负担得起迁移到 Java 8,您可以用新的 StampedLock 替换 ReentrantReadWriteLock
此版本附带的。参见 this answer一个简短的例子和好处。
关于java - ReentrantReadWriteLock 读锁的性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26087738/