源代碼查看,有三個常量,
static final int DEFAULT_INITIAL_CAPACITY = 16;
static final int MAXIMUM_CAPACITY = 1 << 30;
static final float DEFAULT_LOAD_FACTOR = 0.75f;
三個常量中可以看出,默認的容器大小是16,最大長度是2的30次方,load factor默認是0.75,擴充的臨界值是16*0.75=12
當我們往HashMap中put元素的時候,先根據key的hashCode重新計算hash值,根據hash值得到這個元素在數組中的位置(即下標),如果數組該位置上已經存放有其他元素了,那么在這個位置上的元素將以鏈表的形式存放,新加入的放在鏈頭,最先加入的放在鏈尾。如果數組該位置上沒有元素,就直接將該元素放到此數組中的該位置上。
那么hashmap什么時候進行擴容呢?當hashmap中的元素個數超過數組大小*loadFactor時,就會進行數組擴容,loadFactor的默認值為0.75,也就是說,默認情況下,數組大小為16,那么當hashmap中元素個數超過16*0.75=12的時候,就把數組的大小擴展為2*16=32,即擴大一倍,然后重新計算每個元素在數組中的位置,而這是一個非常消耗性能的操作,所以如果我們已經預知hashmap中元素的個數,那么預設元素的個數能夠有效的提高hashmap的性能。
ConcurrentHashMap和Hashtable主要區別就是圍繞着鎖的粒度以及如何鎖。如圖
左邊便是Hashtable的實現方式---鎖整個hash表;而右邊則是ConcurrentHashMap的實現方式---鎖桶(或段)。ConcurrentHashMap將hash表分為16個桶(默認值),諸如get,put,remove等常用操作只鎖當前需要用到的桶。試想,原來只能一個線程進入,現在卻能同時16個寫線程進入(寫線程才需要鎖定,而讀線程幾乎不受限制,之后會提到),並發性的提升是顯而易見.
想要對ConcurrentHashMap如何實現鎖粒度控制和如何鎖,還需研讀ConcurrentHashMap源碼。