Synchronized vs ReadWriteLock performance

馋奶兔 提交于 2019-12-05 14:39:40

The actual cost of acquiring a ReadWriteLock is generally much slower than the cost of acquiring a simple mutex. The javadoc for ReadWriteLock goes into this:

Whether or not a read-write lock will improve performance over the use of a mutual exclusion lock depends on the frequency that the data is read compared to being modified, the duration of the read and write operations, and the contention for the data - that is, the number of threads that will try to read or write the data at the same time. For example, a collection that is initially populated with data and thereafter infrequently modified, while being frequently searched (such as a directory of some kind) is an ideal candidate for the use of a read-write lock. However, if updates become frequent then the data spends most of its time being exclusively locked and there is little, if any increase in concurrency. Further, if the read operations are too short the overhead of the read-write lock implementation (which is inherently more complex than a mutual exclusion lock) can dominate the execution cost, particularly as many read-write lock implementations still serialize all threads through a small section of code. Ultimately, only profiling and measurement will establish whether the use of a read-write lock is suitable for your application.

So the fact that your threads are doing very simple operations may mean that performance is dominated by the amount of time spent actually acquiring the lock.

There's another problem with your benchmarks, which is that Math.random is synchronized. From its javadoc:

This method is properly synchronized to allow correct use by more than one thread. However, if many threads need to generate pseudorandom numbers at a great rate, it may reduce contention for each thread to have its own pseudorandom-number generator.

So even though your concurrent readers are not blocking each other in acquiring the ReadWriteLock, they may still be contending for the lock acquired in Math.random, defeating some of the upside of using the ReadWriteLock. You can improve this by instead using ThreadLocalRandom.

Also, as assylias points out, naive Java benchmarks which don't take into account JIT compilation and other runtime quirks are unreliable. You should use the Java Microbenchmarking Harness (JMH) for benchmarks like these.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!