[英]What is the best way to atomic-replace all contents in List in Java?
Suppose that I have a List
with role of cache. 假设我有一个具有缓存角色的
List
。 Most time list is read-only buy every few seconds I want to do atomic replacement of all List contents. 大多数时间列表是只读的,每隔几秒我就要做所有List内容的原子替换。
In atomic I mean that I don't want to allow cache clients to hit read between for example clear()
and addAll()
. 在原子上我的意思是我不想让缓存客户端在例如
clear()
和addAll()
之间进行读取。
What list implementation to use and how to perform replacement for best performance? 要使用哪个列表实现以及如何执行替换以获得最佳性能?
It is better to replace list contents or to replace reference value itself? 替换列表内容或替换参考值本身更好?
Java has a ReadWriteLock which supports reads concurrently and writes exclusively. Java有一个ReadWriteLock ,它支持并发读取和独占写入。 As mentioned in the JavaDoc, it is a good choice if updates occur not very frequently and reads occur often.
正如JavaDoc中所提到的,如果更新不是经常发生并且经常进行读取,那么它是一个很好的选择。 The faster your writer updates the
List
the better the performance you get. 编写器更新
List
的速度越快,获得的性能越好。
The methods readLock() has to be called by readers and writeLock() by writers. 方法readLock()必须由读者调用,writeLock()必须由编写者调用。 Then you have to call lock() on the Lock obtained.
然后你必须在获得的锁上调用lock()。 If it is available, the tread will continue working, otherwise it will block, until the lock is available.
如果可用,胎面将继续工作,否则它将阻塞,直到锁定可用。
Use fairness when constructing the ReadWriteLock
to enable reader and writer threads to obtain their locks in the order they requested it. 在构造
ReadWriteLock
时使用公平性,以使读取器和写入器线程能够按照它们请求的顺序获取锁定。 Otherwise some thread could wait forever (in a worst case scenario). 否则一些线程可能永远等待(在最坏的情况下)。
The benefit of a ReadWriteLock
is that many reader may share the same lock without obtaining it, which is an expansive operation. ReadWriteLock
的好处是许多读者可以共享相同的锁而无法获得它,这是一个广泛的操作。 This benefit is only observable if the ratio between reading and writing is heavily in favor of reading. 只有在阅读和写作之间的比例大大有利于阅读时,才能观察到这种好处。
If you really want to use the List<>
type for a cache, you can use a lock like: 如果您确实要使用
List<>
类型作为缓存,可以使用如下锁定:
private static final Objet cacheLock = new Object();
public void updateListCache()
{
synchronized(lock)
{
//update your list cache
}
}
Your read operation would also need to implement this lock, or it wouldn't be much use. 您的读取操作也需要实现此锁定,否则它将没有多大用处。
But for caching purposes I would personally go with ConcurrentHashMap since it's thread safe. 但是出于缓存目的,我个人会使用ConcurrentHashMap,因为它是线程安全的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.