4

我正在阅读 的文档java.util.HashMap,它说:

如果多个线程同时访问此映射,并且至少有一个线程在结构上修改了映射,则必须在外部进行同步。

这是什么意思?“它”可以解释为表示修改映射的线程,也可以表示映射本身。

“多线程读取安全”和“只有在有编写器时才在单线程上安全”两种情况都不是明智之举(至少对我而言),这让我相信在文档意味着该语句应该被解释为“安全地读取多个线程和一个线程写入”,而不是“当你有一个作家时锁定一切”。

更重要的是,.Net 中的哈希表实现(明确地)记录为:

Hashtable 是线程安全的,可供多个读取线程和单个写入线程使用

(默认情况下,.Net 类不是线程安全的),因此“多个读取器线程和一个单个写入器线程”的情况必须有一些东西。

4

2 回答 2

2

当线程“在结构上修改映射”时,内部元素处于不确定状态,因此可能会影响读取。因此需要使用映射外部的某种方法来同步读取和写入。

也许 .Net 库的编写者在更新期间更小心地将其内部结构保持在确定状态。

于 2012-09-16T02:52:26.120 回答
0

地图本身。HashMap 不是线程安全的。

看看ConcurrentHashMap,它是一个线程安全的映射。

您也可以自己管理。代码可能如下所示

class SomeClass {

    private Map<Object, Object> map = new HashMap<Object, Object>();

    public synchronized void put(Object key, Object value) {
        map.put(key, value);
    }

    public synchronized Object get(Object key) {
        return map.get(key);
    }
}

更安全的是,返回值对象的副本以避免意外行为。

public synchronized ValueType get(Object key) {
    return map.get(key).clone(); // assume that the ValueType implements Cloneable
    // of course, you can return a copy in many ways you like
}

这将只允许该put方法修改地图。并且所有操作都是线程安全的。

于 2012-09-16T02:55:21.640 回答