Java:同步容器與併發容器有什麼區別?

何爲同步容器:可以簡單地理解爲通過synchronized來實現同步的容器,如果有多個線程調用同步容器的方法,它們將會串行執行。比如Vector,Hashtable,以及Collections.synchronizedSet,synchronizedList等方法返回的容器。

可以通過查看Vector,Hashtable等這些同步容器的實現代碼,可以看到這些容器實現線程安全的方式就是將它們的狀態封裝起來,並在需要同步的方法上加上關鍵字synchronized。

對於Vector,雖然能保證每一個時刻只能有一個線程訪問它,但是不排除這種可能:

當某個線程在某個時刻執行這句時:

for(int i=0;i<vector.size();i++) {
    vector.get(i);
}

假若此時vector的size方法返回的是10,i的值爲9

然後另外一個線程執行了這句:

for(int i=0;i<vector.size();i++) {
    vector.remove(i);
}

那麼通過get方法訪問下標爲9的元素肯定就會出問題了。  

將下標爲9的元素刪除了。


同步容器會導致多個線程中對容器方法調用的串行執行,降低併發性,因爲它們都是以容器自身對象爲鎖,所以在需要支持併發的環境中,可以考慮使用併發容器來替代。

併發容器:併發容器是針對多個線程併發訪問設計的,在jdk5.0引入了concurrent包,其中提供了很多併發容器,如ConcurrentHashMap,CopyOnWriteArrayList等。併發容器使用了與同步容器完全不同的加鎖策略來提供更高的併發性和伸縮性,例如在ConcurrentHashMap中採用了一種粒度更細的加鎖機制,可以稱爲分段鎖,在這種鎖機制下,允許任意數量的讀線程併發地訪問map,並且執行讀操作的線程和寫操作的線程也可以併發的訪問map,同時允許一定數量的寫操作線程併發地修改map,所以它可以在併發環境下實現更高的吞吐量。

另外併發容器提供了一些在使用同步容器時需要自己實現的複合操作,包括putIfAbsent等,但是由於併發容器不能通過加鎖來獨佔訪問,所以我們無法通過加鎖來實現複合操作了。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章