我想有几个柜台,我可以按名称处理。因此,我可以通过以下方式实现它:
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
map.computeIfAbsent("key", k -> new Integer(0));
map.computeIfPresent("key", (k, v) -> v + 1);
它对线程安全进行编码吗?
我这样认为,因为由于ConcurrentHashMap
我们具有同步访问,并且设置新的引用也是线程安全的操作。由于安全发布,其他线程将看到此更改,这是在我们将存储桶锁保留在ConcurrentHashMap
中时发生的。
ConcurrentHashMap.computeIfPresent()
的调用不仅会调用以线程安全的方式传递的表达式,而且还可以保证,如果其他线程尝试同时作用于相同的键,它们将被阻塞并排入队列,以便所有变异都按顺序发生(在分布式系统中,这称为可序列化)。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);