我有一些类似于地图的存储空间。我一直在使用synchronized(this)
get
和put
方法。由于此存储主要用于阅读,因此我考虑使用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。
答案 0 :(得分:3)
您需要确保多个线程看到好处,因为ReentrantReadWriteLock比简单synchronized
更复杂。在synchronized
的情况下,如果JVM看到只有一个线程,它可能会同步优化和删除同步。但这里也引用了ReentrantReadWriteLock javadoc:
ReentrantReadWriteLocks可用于改善某些内容的并发性 使用某些类型的集合。这通常是值得的 当收集预计很大,更多的读者访问 线程比编写器线程,并带来开销的操作 超过同步开销。
如果您负担得起迁移到Java 8,则可以使用此版本附带的新StampedLock替换ReentrantReadWriteLock
。有关简短示例和优势,请参阅this answer。