Java嵌套ConcurrentHashMap是线程安全的吗?

Iva*_*van 5 java multithreading hashmap thread-safety

所以这是实施..

public ConcurrentMap<String , ConcurrentMap<String, Object>> map = new ConcurrentHashMap<>();

public void put(String subKey, String key, Object value) {
    map.putIfAbsent(subKey, new ConcurrentHashMap<>());
    map.get(subKey).put(key, value);
}

public Object get(String subKey, String key) {
    return map.get(subKey) == null ? null : map.get(subKey).get(key);
}
Run Code Online (Sandbox Code Playgroud)

Put 看起来是线程安全的

  • PutIfAbsent 是原子操作。
  • 然后获取内部映射并放置值也应该是线程安全的,正如我认为的那样。

感谢您的任何澄清

And*_*eas 5

在该put方法中,您总是创建一个新的ConcurrentHashMap,即使不需要它。那是浪费。

此外,在该方法中,如果另一个线程可以删除映射键,则可以在和调用put之间删除嵌套映射,从而导致. 改用:putIfAbsentgetNullPointerExceptioncomputeIfAbsent

public void put(String subKey, String key, Object value) {
    map.computeIfAbsent(subKey, k -> new ConcurrentHashMap<>())
       .put(key, value);
}
Run Code Online (Sandbox Code Playgroud)

在该get方法中,您不应调用get两次,因为第一次和第二次调用之间的值可能会发生变化。将值保存为变量:

public Object get(String subKey, String key) {
    ConcurrentMap<String, Object> subMap = map.get(subKey);
    return subMap == null ? null : subMap.get(key);
}
Run Code Online (Sandbox Code Playgroud)

  • @user2864740 我不同意。如果另一个线程删除了“subKey”或“key”,则效果将是删除发生在此“get(subKey, key)”方法调用之前或之后,即使它发生在两个“get()”之间方法中调用。即使您对此进行同步,也不会改变整体*效果*。 (2认同)