2.hashMap如何保證執行緒安全
一:hashMap執行緒不安全表現
(1)在兩個執行緒同時嘗試擴容HashMap時,可能將一個連結串列形成環形的連結串列,所有的next都不為空,進入死迴圈;
(2)在兩個執行緒同時進行put時可能造成一個執行緒資料的丟失;
二:如何執行緒安全的使用hashMap
(1)Hashtable
//Hashtable
Map<String, String> hashtable =
new
Hashtable<>();
HashTable原始碼中是使用synchronized
來保證執行緒安全的,比如下面的get方法和put方法:
1 2 3 4 5 6 |
|
所以當一個執行緒訪問HashTable的同步方法時,其他執行緒如果也要訪問同步方法,會被阻塞住。舉個例子,當一個執行緒使用put方法時,另一個執行緒不但不可以使用put方法,連get方法都不可以,所以效率很低,基本不會選擇它。
(2)ConcurrentHashMap
//ConcurrentHashMap
Map<String, String> concurrentHashMap =
new
ConcurrentHashMap<>();
在jdk1.8中ConcurrentHashMap利用CAS演算法
(3)SynchronizedMap
//synchronizedMap
Map<String, String> synchronizedHashMap = Collections.synchronizedMap(
new
HashMap<String, String>());
static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {
|
從原始碼中可以看出呼叫synchronizedMap()方法後會返回一個SynchronizedMap類的物件,而在SynchronizedMap類中使用了synchronized同步關鍵字來保證對Map的操作是執行緒安全的。