日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

并发编程-13线程安全策略之两种类型的同步容器

發(fā)布時間:2025/3/21 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 并发编程-13线程安全策略之两种类型的同步容器 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 腦圖
  • 概述
  • 同步容器
    • 集合接口下的同步容器實現(xiàn)類
      • Vector (線程安全性比ArrayList好一些,但并非絕對線程安全)
      • 同步容器 線程不安全的場景
      • 其他注意事項
      • Hashtable
    • Collections.synchronizedXXX方法所創(chuàng)建的同步容器
    • Collections.synchronizedList
    • Collections.synchronizedMap
    • Collections.synchronizedSet
  • 小結(jié)
  • 代碼

腦圖


概述

上篇 并發(fā)編程-12線程安全策略之常見的線程不安全類講了一些常用的線程不安全的集合容器(ArrayList、HashMap、HashSet),如果有多個線程并發(fā)訪問這些集合時就會出現(xiàn)線程不安全的問題。 當(dāng)我們在使用這些容器時,需要我們自己來處理線程安全的問題。 使用起來相對會有些不便,而Java在這方面提供了相應(yīng)的同步容器,我們可以在多線程情況下可以結(jié)合實際場景考慮使用這些同步容器。


同步容器


集合接口下的同步容器實現(xiàn)類

  • Vector的方法都是由synchronized關(guān)鍵字保護(hù)


ctrl + o,方法左側(cè) 帶有,就可以看出是個同步方法。


  • Stack繼承了Vector,并且提供了棧操作(先進(jìn)后出)

  • Hashtable也是由synchronized關(guān)鍵字保護(hù)

Vector (線程安全性比ArrayList好一些,但并非絕對線程安全)

ArrayList線程不安全的例子:
https://blog.csdn.net/yangshangwei/article/details/87887613#ArrayList__121

運行結(jié)果:

這種情況下 ,多線程 計算結(jié)果正確


同步容器 線程不安全的場景

同步容器也并不一定是絕對線程安全的,例如有兩個線程,線程A根據(jù)size的值循環(huán)執(zhí)行remove操作,而線程B根據(jù)size的值循環(huán)執(zhí)行執(zhí)行g(shù)et操作。它們都需要調(diào)用size獲取容器大小,當(dāng)循環(huán)到最后一個元素時,若線程A先remove了線程B需要get的元素,那么就會報越界錯誤

Vector中的方法都進(jìn)行了同步處理,那么一定就是線程安全的,事實上這可不一定 。來演示下

運行結(jié)果: java.lang.ArrayIndexOutOfBoundsException

我們來分析一下:

Vector是線程安全的,為什么還會報這個錯?對于Vector,雖然能保證每一個時刻只能有一個線程訪問它,但是不排除這種可能:

當(dāng)某個線程在某個時刻執(zhí)行這句時:

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

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

然后另外一個線程執(zhí)行了這句:

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

將下標(biāo)為9的元素刪除了, 那么通過get方法訪問下標(biāo)為9的元素肯定就會出問題了。

因此為了保證線程安全,必須在方法調(diào)用端做額外的同步措施


其他注意事項

當(dāng)我們使用foreach循環(huán)或迭代器去遍歷元素的同時又執(zhí)行刪除操作的話,即便在單線程下也會報并發(fā)修改異常.

所以在foreach循環(huán)或迭代器遍歷的過程中不能做刪除操作,若需遍歷的同時進(jìn)行刪除操作的話盡量使用for循環(huán)。實在要使用foreach循環(huán)或迭代器的話應(yīng)該先標(biāo)記要刪除元素的下標(biāo),然后最后再統(tǒng)一刪除. 如果使用JDK8,可以使用函數(shù)式編程


Hashtable

線程不安全的HashMap
https://blog.csdn.net/yangshangwei/article/details/87887613#HashMap__130

運行結(jié)果:


Collections.synchronizedXXX方法所創(chuàng)建的同步容器

Collections類中提供了多個synchronizedXxx方法, 該方法返回指定集合對象對應(yīng)的同步對象,從而可以解決多線程并發(fā)訪問集合時的線程安全問題

Collections.synchronizedList


運行結(jié)果: 線程安全


Collections.synchronizedMap

運行結(jié)果: 線程安全


Collections.synchronizedSet

運行結(jié)果: 線程安全


小結(jié)

同步容器是通過synchronized來實現(xiàn)同步的,所以性能較差。而且同步容器也并不是絕對線程安全的,在一些特殊情況下也會出現(xiàn)線程不安全的行為。那么有沒有更好的方式代替同步容器呢?----> 那就是**并發(fā)容器,有了并發(fā)容器后同步容器的使用也越來越少的,大部分都會優(yōu)先使用并發(fā)容器(J.U.C)**. 下篇博文我們討論下J.U.C

總之一句話,優(yōu)先使用并發(fā)容器提供的集合,而不是使用加了鎖的同步容器中的集合


代碼

https://github.com/yangshangwei/ConcurrencyMaster

總結(jié)

以上是生活随笔為你收集整理的并发编程-13线程安全策略之两种类型的同步容器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。