我正在为电子选举计票,初始版本中只有一个政党。每个选民将有不同的线程,并且线程将更新给定政党的投票数。
我决定使用ConcurrentHashMap,但结果并非我所预期...
Map<String, Integer> voting = new ConcurrentHashMap<>();
for (int i = 0; i < 16; i++) {
new Thread(() -> {
voting.put("GERB", voting.getOrDefault("GERB", 0) + 1);
}).start();
}
for (int i = 0; i < 100; i++) {
voting.put("GERB", voting.getOrDefault("GERB", 0) + 1);
}
Thread.sleep(5000); // Waits for the threads to finish
for (String s : voting.keySet()) {
System.out.println(s + ": " + voting.get(s));
}
结果每次都不同 - 范围在114到116之间。
ConcurrentHashMap不是应该是同步的吗?
synchronized(voting)
时,您是在保护其他线程使用synchronized (voting)
,但并不能防止未经同步的put
调用等并发修改。您需要在每个访问上都包装一个这样的同步块才能使其正常工作,这违背了使用ConcurrentHashMap的整个目的。 - Holgerput
和get
方法,也不会损坏映射或值。即get
方法将返回先前的值或新值。 - AterLux