ConcurrentHashMap和Locks

时间:2013-10-27 02:39:23

标签: java

我有一个这样的课。

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来维护吗? 保存时数据的完整性?

3 个答案:

答案 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);
    }