当可以在另一个线程中更新时,使用hashmap值引用是否安全

时间:2017-04-06 05:21:13

标签: java multithreading hashmap concurrenthashmap

使用 getParameter

是否安全

因为我可以容忍价值不是最新的。
下次我可以获得参数

的最新值

这样的代码:

 public class ParameterManager {

    private volatile Map<String, Parameter> scenarioParameterMap = Maps.newHashMap();

    public ParameterManager(String appName) throws DarwinClientException {
    }

    public Parameter getParameter(String scenario) {
        return scenarioParameterMap.get(scenario);
    }

    public void update(String scenario, Map<String, String> parameters) {
         if (scenarioParameterMap.containsKey(scenario)) {
             Parameter parameter = scenarioParameterMap.get(scenario);
             parameter.update(parameters);
         } else {
            scenarioParameterMap.put(scenario, new Parameter(scenario, parameters));
        }
    }
}

或更新只是使用

             scenarioParameterMap.put(scenario, new Parameter(scenario, parameters));

1 个答案:

答案 0 :(得分:3)

volatile根本没有帮助。它仅保护scenarioParameterMap中保存的引用,而不保护该映射的内容。由于您不会在任何时候将其重新指定为指向不同的地图,因此volatile无关紧要。

此代码线程安全。您需要使用正确的同步,通过synchronized或使用concurrent map或其他等效方法。

  

因为我可以忍受这个价值不是最新的。

线程不安全可能比这更危险。它可能会给你错误的结果。它可能会崩溃。你不能认为最坏的情况是陈旧的数据。事实并非如此。

想象一下,Map.put()正在更新地图,并且内部数据处于暂时无效的状态。如果Map.get()同时运行谁知道可能出错的地方。有时在哈希映射中添加一个条目会导致整个事情被重新分配并重新分配。那时读地图的另一个线程会非常困惑。