我知道ConcurentHasMap的计算方法是原子的,但它每次都在相同的锁(节点锁)下访问值吗?因此更具体地说,以下关于地图值的线程安全访问的等价词,在本例中是Set?我可以用idiom1完全替换idiom3吗?
ConcurrentHashMap<String, Set<String>> concurrentMap = new ConcurrentHashMap<>();
Object setLock = new Object();
String testValueToAdd = "valueToAdd";
String testValueToRemove = "valueToRemove";
// idiom 1
// adding
concurrentMap.compute("test", (key, setForTheKey) -> {
if(setForTheKey == null) {
setForTheKey = new HashSet<>();
}
setForTheKey.add(testValueToAdd);
return setForTheKey;
});
// removing
concurrentMap.compute("test", (key, setForTheKey) -> {
if(setForTheKey != null) {
setForTheKey.remove(testValueToRemove);
}
return setForTheKey;
});
// idiom 2, concurrent HashSet
// adding
concurrentMap.putIfAbsent("test", ConcurrentHashMap.newKeySet());
concurrentMap.get("test").add(testValueToAdd);
// removing
Set<String> set = concurrentMap.get("test");
if(set != null) {
set.remove(testValueToRemove);
}
// idiom 3, normal Set
// adding
concurrentMap.putIfAbsent("test", new HashSet<>());
Set<String> normalSet = concurrentMap.get("test").
synchronized(setLock) {
normalSet.add(testValueToAdd);
}
// removing
normalSet = concurrentMap.get("test");
if(normalSet!= null){
synchronized(setLock) {
normalSet.remove(testValueToRemove);
}
}
如果以下习语相同,哪一个应该是首选? idiom3)手动锁定 - &gt;容易出错 idiom2)并发哈希集有点重,使用锁定内部 idiom1)应该与idiom3效率相同,但没有手动锁定对我来说最好。