HashMap:对于多个读者和一个单独的编写者,可以安全地进行多线程访问吗?

时间:2012-09-16 02:39:38

标签: java concurrency hashmap

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

  

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

“它”是什么意思?“它”可以解释为修改地图的线程,或者它可能意味着地图本身。

“有多个线程读取的安全”和“只有在有作者的情况下只在单线程上安全”的情况都不是脑子(至少对我而言),这让我相信称为“多个读者和单个作者”在文档中特定的情况意味着该语句应该被解释为“安全地让多个线程读取和单个线程写入”,而不是没有脑子“当你有一个作家时锁定所有东西”。

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

  

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

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

2 个答案:

答案 0 :(得分:2)

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

.Net库的编写者在更新期间可能会更谨慎地将其内部结构保持在确定状态。

答案 1 :(得分: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方法修改地图。并且所有操作都是线程安全的。