天天看點

什麼情況下用ConcurrentHashMap

很多同僚都了解了HashMap和ConcurrentHashMap的原理,并且也看了兩個類的源碼,但是還是不知道在什麼情況下使用ConcurrentHashMap。

1,在多線程并發向HashMap中put資料時,就需要把HashMap換成ConcurrentHashMap。

(原因為并發向HashMap中put資料會出現死循環,導緻CPU使用率暴增。參考參考:http://mailinator.blogspot.com/2009/06/beautiful-race-condition.html)

2,在業務中可以使用ConcurrentMap接口中定義的方法解決并發問題時。

public interface ConcurrentMap<K, V> extends Map<K, V> {
    V putIfAbsent(K key, V value);
    boolean remove(Object key, Object value);
    boolean replace(K key, V oldValue, V newValue);
    V replace(K key, V value);
}
           

舉個例子

private final Map<String, Long> wordCounts = new ConcurrentHashMap<>();
 
public long increase(String word) {
    Long oldValue = wordCounts.get(word);
    Long newValue = (oldValue == null) ? 1L : oldValue + 1;
    wordCounts.put(word, newValue);
    return newValue;
}
           

 替換為

private final ConcurrentMap<String, Long> wordCounts = new ConcurrentHashMap<>();
 
public long increase(String word) {
    Long oldValue, newValue;
    while (true) {
        oldValue = wordCounts.get(word);
        if (oldValue == null) {
            // Add the word firstly, initial the value as 1
            newValue = 1L;
            if (wordCounts.putIfAbsent(word, newValue) == null) {
                break;
            }
        } else {
            newValue = oldValue + 1;
            if (wordCounts.replace(word, oldValue, newValue)) {
                break;
            }
        }
    }
    return newValue;
}