ConcurrentHashMap的计算方法是否以线程安全的方式访问映射的值?

时间:2018-02-23 14:44:29

标签: java multithreading concurrency concurrenthashmap

我知道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效率相同,但没有手动锁定对我来说最好。

0 个答案:

没有答案