Java Maps
HashMap
-
是線程不安全的,主要對于寫操作來說,兩個以上線程同時寫入Map會被互相覆蓋。線程安全指的保證對同一個map的寫入操作按照順序進行,一次只能一個線程更改。比如向HashMap里put(key, value1)有可能key對應的是其他線程同時寫入的value2
-
HashMap的遍歷有兩種常用的方法,那就是使用keyset及entryset來進行遍歷,但兩者的遍歷速度是有差別的.
第一種:
// 效率高,以后一定要使用此種方式!Map map = new HashMap();Iterator iter = map.entrySet().iterator();while (iter.hasNext()) {Map.Entry entry = (Map.Entry) iter.next();Object key = entry.getKey();Object val = entry.getValue();}
第二種:
// 效率低,以后盡量少使用!Map map = new HashMap();Iterator iter = map.keySet().iterator();while (iter.hasNext()) {Object key = iter.next();Object val = map.get(key);}
-
HashMap或者ArrayList邊遍歷邊刪除數據會報java.util.ConcurrentModificationException異常,需要用Iterator遍歷刪除。ConcurrentHashMap沒有這種問題。
-
對于ArrayList,不要在 foreach 循環里進行元素的 remove/add 操作。remove 元素請使用 Iterator 方式,如果并發操作,需要對 Iterator 對象加鎖。
?
//WrongList<String> a = new ArrayList<String>();a.add("1"); a.add("2"); for (String temp : a) {if("1".equals(temp)){ a.remove(temp); } }ConcurrentHashMap
-
public V get(Object key)不涉及到鎖,也就是說獲得對象時沒有使用鎖,保證讀到最新的值
-
put、remove方法要使用鎖,但并不一定有鎖爭用,原因在于ConcurrentHashMap將緩存的變量分到多個Segment,每個Segment上有一個鎖,只要多個線程訪問的不是一個Segment就沒有鎖爭用,就沒有堵塞,各線程用各自的鎖,ConcurrentHashMap缺省情況下生成16個Segment,也就是允許16個線程并發的更新而盡量沒有鎖爭用;
-
Iterator對象的使用,不一定是和其它更新線程同步,獲得的對象可能是更新前的對象,ConcurrentHashMap允許一邊更新、一邊遍歷,也就是說在Iterator對象遍歷的時候,ConcurrentHashMap也可以進行remove,put操作,且遍歷的數據會隨著remove,put操作產出變化,所以希望遍歷到當前全部數據的話,要么以ConcurrentHashMap變量為鎖進行同步(synchronized該變量),要么使用CopiedIterator包裝iterator,使其拷貝當前集合的全部數據,但是這樣生成的iterator不可以進行remove操作。
-
ConcurrentHashMap is much quicker than SynchronizedHashMap. ConcurrentHashMap所使用的鎖分段技術,首先將數據分成一段一段的存儲,然后給每一段數據配一把鎖,當一個線程占用鎖訪問其中一個段數據的時候,其他段的數據也能被其他線程訪問。
-
對ConcurrentHashMap邊遍歷邊刪除或者增加操作不會產生異常(可以不用迭代方式刪除元素),因為其內部已經做了維護,遍歷的時候都能獲得最新的值。即便是多個線程一起刪除、添加元素也沒問題。
-
ConcurrentHashMap或者說所有的Map都不保證非原子性的操作,比如判斷contains后再get的值可能已經改變,需要對整個Map加鎖
-
You should use ConcurrentHashMap when you need very high concurrency in your project.
-
It is thread safe without synchronizing the whole map.
-
Reads can happen very fast while write is done with a lock.
-
There is no locking at the object level.
-
The locking is at a much finer granularity at a hashmap bucket level.
-
ConcurrentHashMap doesn’t throw a ConcurrentModificationException if one thread tries to modify it while another is iterating over it.
-
ConcurrentHashMap uses multitude of locks
HashTable
-
線程安全,但是對整個Map上鎖,讀和寫都需要同步,在高競爭環境下效率很低,有Scalability 的問題
HashMap
-
Note that this implementation is not synchronized. If multiple threads access a hashmap concurrently, and at least one of the threads modifies the map structurally, it must be synchronized externally. (A structural modification is any operation that adds or deletes one or more mappings; merely changing the value associated with a key that an instance already contains is not a structural modification.) This is typically accomplished by synchronizing on some object that naturally encapsulates the map. If no such object exists, the map should be "wrapped" using the Collections.synchronizedMap method. This is best done at creation time, to prevent accidental unsynchronized access to the map
SynchronizedHashMap
-
Synchronization at Object level.
-
Every read/write operation needs to acquire lock.
-
Locking the entire collection is a performance overhead.
-
This essentially gives access to only one thread to the entire map & blocks all the other threads.
-
It may cause contention.
-
SynchronizedHashMap returns Iterator, which fails-fast on concurrent modification.
| 集合類 | Key | Value | Super | 說明 |
| Hashtable | 不允許為 null | 不允許為 null | Dictionary | 線程安全 |
| ConcurrentHashMap | 不允許為 null | 不允許為 null | AbstractMap | 線程局部安全 |
| TreeMap | 不允許為 null | 允許為 null | AbstractMap | 線程不安全 |
| HashMap | 允許為 null | 允許為 null | AbstractMap | 線程不安全 |
轉載于:https://www.cnblogs.com/codingforum/p/6434518.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
- 上一篇: VSCode从非根目录编译golang程
- 下一篇: bzoj 3209: 花神的数论题