我們知道,普通的集合類ArrayList、LinkedList、HashMap等等是線程不安全的,即:在多線程共同操作這些類對象時,會發生競態條件或者操作異常。如果我們需要在多線程下使用這些集合類,就需要顯式地進行同步操作(用syncrhoized關鍵字等對集合類的操作代碼加同步鎖)。如果不想這么麻煩,我們可以使用Java提供的同步容器,同步容器默認是線程安全的,對它的操作都是已經默認加了同步鎖的。
一:同步容器
同步容器主要包括2類:
1)Vector、Stack、HashTable
Vector實現了List接口,Vector底層是一個數組,其對於數組的各種操作和ArrayList幾乎一樣,唯一不同的在於大部分線程不安全的方法都加了syncrhoized關鍵字去限定。
Stack底層也是一個數組,它繼承於Vector類,很多方法也用syncrhoized關鍵字加了鎖。
HashTable實現了Map接口,它的實現原理幾乎和HashMap一樣。但是HashTable對很多方法都加了syncrhoized關鍵字進行限定。
2)Collections 工具類中提供的同步集合類
Collections類是一個工具類,相當於Arrays類對於Array的支持,Collections類中提供了大量對集合或者容器進行排序、查找的方法。它還提供了幾個靜態方法來創建同步容器類:
二:並發容器
同步容器是通過syncrhoized關鍵字對線程不安全的操作進行加鎖來保證線程安全的,其原理是使得多線程輪流獲取同步鎖進行對集合的操作,所以性能有所下降。
為此,java.util.concurrent提供了多種並發容器,以:在原有集合的拷貝上進行操作,用修改后的集合替換原集合 的方式來達到並發且安全地使用集合類的目的。
根據接口的類型,主要有以下四種接口,其他具體的容器均是對這些接口的實現類:
- Queue類型:阻塞隊列BlockingQueue、非阻塞隊列ConcurrentLinkedQueue
- Map類型:ConcurrentMap
- Set類型:ConcurrentSkipListSet、CopyOnWriteArraySet
- List類型:CopyOnWriteArrayList
在后面的博文我們將逐個分類一一了解具體的並發容器實現類。