【发布时间】:2018-02-05 17:59:27
【问题描述】:
根据我的理解,ConcurrentHashMap 将允许多个线程在同一个哈希映射上读取和写入(添加/删除),而不会出现并发哈希映射异常。
我有 4 个线程,每个线程都可以更新 hashmap。我不希望其他线程在当前线程更新 hashmap 时写入/更新它。
ConcurrentHashMap<String, Integer> playerLoginCounterHashMap = new ConcurrentHashMap<>();
ExecutorService executorService = Executors.newFixedThreadPool(4);
for (int i = 0; i < 4; i++) {
executorService.submit(new Runnable() {
@Override
public void run() {
synchronized (playerLoginCounterHashMap) {
if (playerLoginCounterHashMap.get("testPlayer") == null) {
playerLoginCounterHashMap.put("testPlayer", 1);
} else {
playerLoginCounterHashMap.put("testPlayer", playerLoginCounterHashMap.get("testPlayer").intValue() + 1);
}
}
}
});
}
这是正确的做法吗?如果没有同步块,我会得到不正确的值。
【问题讨论】:
-
那个代码会为你生成异常?
-
您需要使用并发感知 API,例如
putIfAbsent或computeIfAbsent以允许并发。否则,如果您的整个更新过程需要是原子的,那么唯一的解决方案是锁定并防止任何其他线程在您更新时使用映射,此时 ConcurrentHashMap 不会为您增加任何价值。跨度> -
@DanielPryden putIfAbsent 似乎不像文档中的 computeIfAbsent 那样是原子的
-
@forum.test17
putIfAbsent仅以原子方式处理“put”操作,这是真的。因此,您需要处理多个线程竞相计算相同的值。compute函数,因为它需要一个 lambda,所以可以为您处理所有这些,但在 Java 的 8 之前版本中,您没有 lambdas 或compute,因此您需要使用像 @987654327 这样的工具自己做@.
标签: java concurrency concurrenthashmap