插入并发哈希映射
inserting in a concurrent hash map
以下代码没有按预期运行。当我在 Does class 中调用 put 方法时,并发哈希映射中的值与映射的不同实例相关联。所以我想做的是多个线程访问同一个映射并为同一个键插入一个值。但是,如果我将 synchronized 关键字添加到 put 方法,它就可以工作。我错过了什么?
class Does implements Runnable {
C2 c2;
Does(C2 c2) {
this.c2 = c2;
}
public void run() {
c2.put("Hello");
}
}
public class C2 {
public ConcurrentHashMap<String, List<String>> map = new ConcurrentHashMap<String, List<String>>();
public static void main(String args[]) {
C2 c2 = new C2();
new Thread(new Does(c2)).start();
new Thread(new Does(c2)).start();
new Thread(new Does(c2)).start();
new Thread(new Does(c2)).start();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
List<String> lu = c2.map.get("Hello");
System.out.println(lu);
}
/**
* @param string
*/
public void put(String string) {
if (map.containsKey(string)) {
List<String> li = map.get(string);
li.add("adding something");
} else {
List<String> li = new ArrayList<String>();
li.add("adding something");
map.put(string, li);
}
}
}
感谢帮助。
这段代码不是线程安全的
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);
}
在Java8中你可以使用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");
}
}
以下代码没有按预期运行。当我在 Does class 中调用 put 方法时,并发哈希映射中的值与映射的不同实例相关联。所以我想做的是多个线程访问同一个映射并为同一个键插入一个值。但是,如果我将 synchronized 关键字添加到 put 方法,它就可以工作。我错过了什么?
class Does implements Runnable {
C2 c2;
Does(C2 c2) {
this.c2 = c2;
}
public void run() {
c2.put("Hello");
}
}
public class C2 {
public ConcurrentHashMap<String, List<String>> map = new ConcurrentHashMap<String, List<String>>();
public static void main(String args[]) {
C2 c2 = new C2();
new Thread(new Does(c2)).start();
new Thread(new Does(c2)).start();
new Thread(new Does(c2)).start();
new Thread(new Does(c2)).start();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
List<String> lu = c2.map.get("Hello");
System.out.println(lu);
}
/**
* @param string
*/
public void put(String string) {
if (map.containsKey(string)) {
List<String> li = map.get(string);
li.add("adding something");
} else {
List<String> li = new ArrayList<String>();
li.add("adding something");
map.put(string, li);
}
}
}
感谢帮助。
这段代码不是线程安全的
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);
}
在Java8中你可以使用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");
}
}