1. 程式人生 > >HashMap、HashTable與ConcurrentHashMap區別

HashMap、HashTable與ConcurrentHashMap區別

執行緒不安全的HashMap

  在多執行緒環境下,使用HashMap進行put操作會引起死迴圈,導致CPU利用率接近100%,所以在併發情況下不能使用HashMap。例如,執行如下程式碼會引起死迴圈。

  1. final HashMap<String, String> map = new HashMap<String, String>(2);  
  2.         Thread t = new Thread(new Runnable() {  
  3.             @Override
  4.             publicvoid run() {  
  5.                 for (
    int i = 0; i < 10000; i++) {  
  6.                     new Thread(new Runnable() {  
  7.                         @Override
  8.                         publicvoid run() {  
  9.                             map.put(UUID.randomUUID().toString(), "");  
  10.                         }  
  11.                     }, "ftf" + i).start();  
  12.                 }  
  13.             }  
  14.         }, "ftf");  
  15.         t.start();  
  16.         t.join();  
  HashMap在併發執行put操作時會引起死迴圈,是因為多執行緒會導致HashMap的Entry連結串列形成環形資料結構,一旦形成環形資料結構,Entry的next節點永遠不為空,就會產生死迴圈獲取Entry。

效率低下的HashTable 

  HashTable容器使用synchronized來保證執行緒安全,但線上程競爭激烈的情況下HashTable的效率非常低下。因為當一個執行緒訪問HashTable的同步方法,其他執行緒也訪問HashTable的同步方法時,會進入阻塞或輪詢狀態。如執行緒1使用put進行元素新增,執行緒2不但不能使用put方法新增元素,也不能使用get方法來獲取元素,所以競爭越激烈效率
越低。

ConcurrentHashMap的鎖分段技術可有效提升併發訪問率

  HashTable容器在競爭激烈的併發環境下表現出效率低下的原因是因為所有訪問HashTable的執行緒都必須競爭同一把鎖,假如容器裡有多把鎖,每一把鎖用於鎖容器其中一部分資料,那麼當多執行緒訪問容器裡不同資料段的資料時,
執行緒間就不會存在鎖競爭,從而可以有效提高併發訪問效率,這就是ConcurrentHashMap所使用的鎖分段技術。首先
將資料分成一段一段地儲存,然後給每一段資料配一把鎖,當一個執行緒佔用鎖訪問其中一個段資料的時候,其他段
的資料也能被其他執行緒訪問。