我有一个这样的课。
public class Cache
{
private static final ConcurrentHashMap<String, Cache>
CACHE = new ConcurrentHashMap<String, Cache>();
ConcurrentHashMap<Long,ClassA> mapA =
new ConcurrentHashMap<String,ClassA>();
ConcurrentHashMap<Long,Date> mapB =
new ConcurrentHashMap<Long,Date>();
}
该类中还有其他几种方法可以添加,删除两个映射中的键。 当线程更新映射时,另一个线程可以为同一个Cache实例更新mapB。 我还需要定期将此缓存保存到磁盘。我需要ReadWriteLocks来维护吗? 保存时数据的完整性?
答案 0 :(得分:1)
据我所知,ConcurrentHashMaps在内部是线程安全的,因此您不需要任何对象锁。 ConcurrentHashMap
支持检索的完全并发和可调整的哈希表 预期的更新并发性。本课程遵循相同的功能 规范为Hashtable,包括方法版本 对应于Hashtable的每种方法。但是,尽管如此 操作是线程安全的,检索操作不需要 锁定,并没有任何支持锁定整个表 一种阻止所有访问的方式。
答案 1 :(得分:0)
这取决于应用程序逻辑。例如,您可以安全地迭代地图的条目并将其保存到文件中,而其他线程正在更改地图。但这不是原子操作。如果您想要一致的快照,则需要同步。
答案 2 :(得分:0)
ConcurrentHashMap的writeObject在序列化之前锁定每个段,因此您不必担心数据完整性。注意:段之间可能存在间隙(当Object被序列化时,非锁定段上的更新)。如果你想在writeObject期间完全锁定,那么使用Collections.synchronizedMap()。
引用方法ConcurrentHashMap.writeObject():
private void writeObject(java.io.ObjectOutputStream s) throws IOException {
// force all segments for serialization compatibility
for (int k = 0; k < segments.length; ++k)
ensureSegment(k);
s.defaultWriteObject();
final Segment<K,V>[] segments = this.segments;
for (int k = 0; k < segments.length; ++k) {
Segment<K,V> seg = segmentAt(segments, k);
seg.lock();
try {
HashEntry<K,V>[] tab = seg.table;
for (int i = 0; i < tab.length; ++i) {
HashEntry<K,V> e;
for (e = entryAt(tab, i); e != null; e = e.next) {
s.writeObject(e.key);
s.writeObject(e.value);
}
}
} finally {
seg.unlock();
}
}
s.writeObject(null);
s.writeObject(null);
}