1. 程式人生 > >2.hashMap如何保證執行緒安全

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

public synchronized V get(Object key) {

// 省略實現

}

public synchronized V put(K key, V value) {

// 省略實現

}

        所以當一個執行緒訪問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>());

// synchronizedMap方法

public

static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {

return new SynchronizedMap<>(m);

}

// SynchronizedMap類

private static class SynchronizedMap<K,V>

implements Map<K,V>, Serializable {

private static final long serialVersionUID = 1978198479659022715L;

private final Map<K,V> m;     // Backing Map

final Object      mutex;        // Object on which to synchronize

SynchronizedMap(Map<K,V> m) {

this.m = Objects.requireNonNull(m);

mutex = this;

}

SynchronizedMap(Map<K,V> m, Object mutex) {

this.m = m;

this.mutex = mutex;

}

public int size() {

synchronized (mutex) {return m.size();}

}

public boolean isEmpty() {

synchronized (mutex) {return m.isEmpty();}

}

public boolean containsKey(Object key) {

synchronized (mutex) {return m.containsKey(key);}

}

public boolean containsValue(Object value) {

synchronized (mutex) {return m.containsValue(value);}

}

public V get(Object key) {

synchronized (mutex) {return m.get(key);}

}

public V put(K key, V value) {

synchronized (mutex) {return m.put(key, value);}

}

public V remove(Object key) {

synchronized (mutex) {return m.remove(key);}

}

// 省略其他方法

}

      從原始碼中可以看出呼叫synchronizedMap()方法後會返回一個SynchronizedMap類的物件,而在SynchronizedMap類中使用了synchronized同步關鍵字來保證對Map的操作是執行緒安全的。