Hashtable和HashMap的區別

1.Hashtable是Dictionary的子類,HashMap是Map接口的一個實現類;
2.Hashtable中的方法是同步的,而HashMap中的方法在缺省情況下是非同步的。即是說,在多線程應用程序中,不用專門的操作就安全地可以使用Hashtable了;而對於HashMap,則需要額外的同步機制。但HashMap的同步問題可通過Collections的一個靜態方法得到解決:
Map Collections.synchronizedMap(Map m)
這個方法返回一個同步的Map,這個Map封裝了底層的HashMap的所有方法,使得底層的HashMap即使是在多線程的環境中也是安全的。

3.在HashMap中,null可以作爲鍵,這樣的鍵只有一個;可以有一個或多個鍵所對應的值爲null。當get()方法返回null值時,即可以表示HashMap中沒有該鍵,也可以表示該鍵所對應的值爲null。因此,在HashMap中不能由get()方法來判斷HashMap中是否存在某個鍵,而應該用containsKey()方法來判斷。


再補充個ConcurrentHashMap 

ConcurrentHashMap 是一個併發散列映射表的實現,它允許完全併發的讀取,並且支持給定數量的併發更新。相比於 HashTable 和用同步包裝器包裝的 HashMap(Collections.synchronizedMap(new HashMap())),ConcurrentHashMap 擁有更高的併發性。在 HashTable 和由同步包裝器包裝的 HashMap 中,使用一個全局的鎖來同步不同線程間的併發訪問。同一時間點,只能有一個線程持有鎖,也就是說在同一時間點,只能有一個線程能訪問容器。這雖然保證多線程間的安全併發訪問,但同時也導致對容器的訪問變成串行化的了。

在使用鎖來協調多線程間併發訪問的模式下,減小對鎖的競爭可以有效提高併發性。有兩種方式可以減小對鎖的競爭:

  1. 減小請求 同一個鎖的 頻率。
  2. 減少持有鎖的 時間。

ConcurrentHashMap 的高併發性主要來自於三個方面:

  1. 用分離鎖實現多個線程間的更深層次的共享訪問。
  2. 用 HashEntery 對象的不變性來降低執行讀操作的線程在遍歷鏈表期間對加鎖的需求。
  3. 通過對同一個 Volatile 變量的寫 / 讀訪問,協調不同線程間讀 / 寫操作的內存可見性。

使用分離鎖,減小了請求 同一個鎖的頻率。

通過 HashEntery 對象的不變性及對同一個 Volatile 變量的讀 / 寫來協調內存可見性,使得 讀操作大多數時候不需要加鎖就能成功獲取到需要的值。由於散列映射表在實際應用中大多數操作都是成功的 讀操作,所以 2 和 3 既可以減少請求同一個鎖的頻率,也可以有效減少持有鎖的時間。

通過減小請求同一個鎖的頻率和儘量減少持有鎖的時間 ,使得 ConcurrentHashMap 的併發性相對於 HashTable 和用同步包裝器包裝的 HashMap有了質的提高。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章