可以将ConcurrentHashMap与Integer一起用于线程安全计数器吗?

问题描述 投票:0回答:2

我想有几个柜台,我可以按名称处理。因此,我可以通过以下方式实现它:

ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
map.computeIfAbsent("key", k -> new Integer(0));
map.computeIfPresent("key", (k, v) -> v + 1);

它对线程安全进行编码吗?

我这样认为,因为由于ConcurrentHashMap我们具有同步访问,并且设置新的引用也是线程安全的操作。由于安全发布,其他线程将看到此更改,这是在我们将存储桶锁保留在ConcurrentHashMap中时发生的。

java multithreading java-8 concurrency concurrenthashmap
2个回答
1
投票
JDK的最新版本保证对ConcurrentHashMap.computeIfPresent()的调用不仅会调用以线程安全的方式传递的表达式,而且还可以保证,如果其他线程尝试同时作用于相同的键,它们将被阻塞并排入队列,以便所有变异都按顺序发生(在分布式系统中,这称为可序列化)。

1
投票
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; public class ThreadsafeExample { public static void main(String[] args) throws Exception { ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>(); int count = 1000; AtomicInteger doneTasks = new AtomicInteger(); Thread[] threads = new Thread[count]; for(int i = 0 ; i < threads.length ; ++i) { threads[i] = new Thread(() -> { map.computeIfAbsent("key", k -> new Integer(0)); map.computeIfPresent("key", (k, v) -> v + 1); doneTasks.incrementAndGet(); }); } for(int i = 0 ; i < threads.length ; ++i) threads[i].start(); while (doneTasks.get() < count) Thread.sleep(3); System.out.println("we expected count of key is: " + count + ", and we get: " + map.get("key")); } }

输出:

we expected count of key is: 1000, and we get: 1000

您可以替换:

map.computeIfAbsent("key", k -> new Integer(0));
map.computeIfPresent("key", (k, v) -> v + 1);

作者

map.compute("key", (k, v) -> v == null ? 1 : v + 1);
© www.soinside.com 2019 - 2024. All rights reserved.