從JDK1.2起,就有了HashMap,正如前一篇文章所說,HashMap不是線程安全的,因此多線程操作時需要格外小心。
在JDK1.5中,偉大的Doug Lea給我們帶來了concurrent包,從此Map也有安全的了。
public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
implements ConcurrentMap<K,V>, Serializable {
private static final long serialVersionUID = 7249069246763182397L;
ConcurrentHashMap具體是怎麼實現線程安全的呢,肯定不可能是每個方法加synchronized,那樣就變成了HashTable。
ConcurrentHashMap引入了一個“分段鎖”的概念,具體可以理解爲把一個大的Map拆分成N個小的HashTable,根據key.hashCode()來決定把key放到哪個HashTable中。
在ConcurrentHashMap中,就是把Map分成了N個Segment,put和get的時候,都是現根據key.hashCode()算出放到哪個Segment中
一、結構解析
ConcurrentHashMap和Hashtable主要區別就是圍繞着鎖的粒度以及如何鎖,可以簡單理解成把一個大的HashTable分解成多個,形成了鎖分離。如圖:
而Hashtable的實現方式是—鎖整個hash表
二、應用場景
當有一個大數組時需要在多個線程共享時就可以考慮是否把它給分層多個節點了,避免大鎖。並可以考慮通過hash算法進行一些模塊定位。
其實不止用於線程,當設計數據表的事務時(事務某種意義上也是同步機制的體現),可以把一個表看成一個需要同步的數組,如果操作的表數據太多時就可以考慮事務分離了(這也是爲什麼要避免大表的出現),比如把數據進行字段拆分,水平分表等.