并发编程-13线程安全策略之两种类型的同步容器
文章目錄
- 腦圖
- 概述
- 同步容器
- 集合接口下的同步容器實現類
- Vector (線程安全性比ArrayList好一些,但并非絕對線程安全)
- 同步容器 線程不安全的場景
- 其他注意事項
- Hashtable
- Collections.synchronizedXXX方法所創建的同步容器
- Collections.synchronizedList
- Collections.synchronizedMap
- Collections.synchronizedSet
- 小結
- 代碼
腦圖
概述
上篇 并發編程-12線程安全策略之常見的線程不安全類講了一些常用的線程不安全的集合容器(ArrayList、HashMap、HashSet),如果有多個線程并發訪問這些集合時就會出現線程不安全的問題。 當我們在使用這些容器時,需要我們自己來處理線程安全的問題。 使用起來相對會有些不便,而Java在這方面提供了相應的同步容器,我們可以在多線程情況下可以結合實際場景考慮使用這些同步容器。
同步容器
集合接口下的同步容器實現類
- Vector的方法都是由synchronized關鍵字保護
ctrl + o,方法左側 帶有,就可以看出是個同步方法。
- Stack繼承了Vector,并且提供了棧操作(先進后出)
- Hashtable也是由synchronized關鍵字保護
Vector (線程安全性比ArrayList好一些,但并非絕對線程安全)
ArrayList線程不安全的例子:
https://blog.csdn.net/yangshangwei/article/details/87887613#ArrayList__121
運行結果:
這種情況下 ,多線程 計算結果正確
同步容器 線程不安全的場景
同步容器也并不一定是絕對線程安全的,例如有兩個線程,線程A根據size的值循環執行remove操作,而線程B根據size的值循環執行執行get操作。它們都需要調用size獲取容器大小,當循環到最后一個元素時,若線程A先remove了線程B需要get的元素,那么就會報越界錯誤
Vector中的方法都進行了同步處理,那么一定就是線程安全的,事實上這可不一定 。來演示下
運行結果: java.lang.ArrayIndexOutOfBoundsException
我們來分析一下:
Vector是線程安全的,為什么還會報這個錯?對于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); }將下標為9的元素刪除了, 那么通過get方法訪問下標為9的元素肯定就會出問題了。
因此為了保證線程安全,必須在方法調用端做額外的同步措施
其他注意事項
當我們使用foreach循環或迭代器去遍歷元素的同時又執行刪除操作的話,即便在單線程下也會報并發修改異常.
所以在foreach循環或迭代器遍歷的過程中不能做刪除操作,若需遍歷的同時進行刪除操作的話盡量使用for循環。實在要使用foreach循環或迭代器的話應該先標記要刪除元素的下標,然后最后再統一刪除. 如果使用JDK8,可以使用函數式編程
Hashtable
線程不安全的HashMap
https://blog.csdn.net/yangshangwei/article/details/87887613#HashMap__130
運行結果:
Collections.synchronizedXXX方法所創建的同步容器
Collections類中提供了多個synchronizedXxx方法, 該方法返回指定集合對象對應的同步對象,從而可以解決多線程并發訪問集合時的線程安全問題
Collections.synchronizedList
運行結果: 線程安全
Collections.synchronizedMap
運行結果: 線程安全
Collections.synchronizedSet
運行結果: 線程安全
小結
同步容器是通過synchronized來實現同步的,所以性能較差。而且同步容器也并不是絕對線程安全的,在一些特殊情況下也會出現線程不安全的行為。那么有沒有更好的方式代替同步容器呢?----> 那就是**并發容器,有了并發容器后同步容器的使用也越來越少的,大部分都會優先使用并發容器(J.U.C)**. 下篇博文我們討論下J.U.C
總之一句話,優先使用并發容器提供的集合,而不是使用加了鎖的同步容器中的集合
代碼
https://github.com/yangshangwei/ConcurrencyMaster
總結
以上是生活随笔為你收集整理的并发编程-13线程安全策略之两种类型的同步容器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 并发编程-12线程安全策略之常见的线程不
- 下一篇: 并发编程-14线程安全策略之并发容器(J