天天看點

HashMap , HashTable , ConcurrentHashMap 源碼比較__v1.0

                   首先,hashmap , hashtable 與 concurrenthashmap 裡面用的 都是 數組(node<k,v>[] table; 與 entry<?,?>[] table;),而且它們都是 transient 的,對于 transient ,效果如下:

                              1)一旦變量被transient修飾,變量将不再是對象持久化的一部分,該變量内容在序列化後無法獲得通路。

                              2)transient關鍵字隻能修飾變量,而不能修飾方法和類。注意,本地變量是不能被        transient關鍵字修飾的。變量如果是使用者自定義類變量,則該類需要實作serializable接口。

                              3)被transient關鍵字修飾的變量不再能被序列化,一個靜态變量不管是否被transient修飾,均不能被序列化。

                        且  concurrenthashmap 中的table同時被聲明為 volatile,意義如下:

                                   1)一個變量聲明為volatile,就意味着這個變量是随時會被其他線程修改的,是以不能将它cache線上程memory中。

                                   2)volatile一般情況下不能代替sychronized,因為volatile不能保證操作的原子性,即使隻是i++,實際上也是由多個原子操作組成:read i; inc; write i,假如多個線程同時執行i++,volatile隻能保證他們操作的i是同一塊記憶體,但依然可能出現寫入髒資料的情況。如果配合java 5增加的atomic wrapper classes,對它們的increase之類的操作就不需要sychronized。 

                           hashmap 與 concurrenthashmap 繼承的是 abstractmap,而 hashtable 繼承的是 dictionary;它們是有差別的: 1,dictionary 允許空鍵和空值,keys()函數傳回的是一個疊代器; 2,abstractmap的keyset傳回的是一個 set,dictionary的方法沒有abstractmap豐富。

                   其次,hashtable與concurrenthashmap是線程安全的,但是方式上不一樣: hashtable 是直接在方法上加 synchronized ; 而concurrenthashmap是在table的node上加synchronized,更加細緻,也更有效率。

                   最後,對于 hashmap 中 沖突後 鍊位址法 的實作(hashtable中用的是 rehash法,對于這一點,從其使用的是 entry<?,?>[] table; 也可以看出),記得在1.7版本看到的是直接加到table中目前節點的前邊添加新沖突的node;但是對于1.8的實作,發現不是直接添加,而是使用 紅黑樹(根據value進行構造) 進行處理