以下代码无法按预期工作。当我在Do类中调用put方法时,并发哈希映射中的值与不同的map实例相关联。所以我想要做的是多个线程访问相同的映射并为同一个键插入一个值。但是,如果我将一个synchronized关键字添加到put方法,它就可以工作。我错过了什么?
--ignore='./node_modules\/(?!node-notifier).+|...'
感谢帮助。
答案 0 :(得分:3)
此代码不是线程安全的
public void put(String string) {
if (map.containsKey(string)) {
// anything can happen in another thread here
List<String> li = map.get(string);
// anything can happen in another thread here
li.add("adding something");
} else {
// anything can happen in another thread here
List<String> li = new ArrayList<String>();
li.add("adding something");
// anything can happen in another thread here
map.put(string, li);
}
在Java 8中,您可以使用computeIfAbsent。
public void put(String string) {
// all most thread safe.
map.computeIfAbsent(string, k -> new ArrayList<>())
.add("add something");
}
注意这仍然不是线程安全的,因为ArrayList不是线程安全的,所以你需要的是
public void put(String string) {
List<String> list = map.computeIfAbsent(string, k -> new ArrayList<>());
synchronized(list) {
list.add("add something");
}
}