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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

JAVA并发-为现有的线程安全类添加原子方法

發(fā)布時間:2025/6/15 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JAVA并发-为现有的线程安全类添加原子方法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

JAVA中有許多線程安全的基礎(chǔ)模塊類,一般情況下,這些基礎(chǔ)模塊類能滿足我們需要的所有操作,但更多時候,他們并不能滿足我們所有的需要。此時,我們需要想辦法在不破壞已有的線程安全類的基礎(chǔ)上添加一個新的原子操作。有如下4中方案:?
1 修改類的源碼,以添加新的原子操作?
2 繼承該線程安全類,并添加原子操作?
3 使用客戶端加鎖方式?
4 使用組合方式(推薦)?
一般來講,修改源碼的方式不太可行,這樣會破壞原有類的封裝性而且有些時候,源碼不可獲得。我們從第二種方式開始舉例:?

假設(shè)現(xiàn)在對于類Vector,我們知道它是線程安全類。如果想為他添加一個“若沒有則添加”方法,可是如下進(jìn)行:?

Java代碼??
  • public?class?ImprovedVector<T>?extends?Vector<T>{??
  • ????public?synchronized?boolean?putIfAbsent(T?x){??
  • ????????boolean?flag=contains(x);??
  • ????????if(!flag)??
  • ?????????????add(x);??
  • ????????return?!flag;??
  • ????}??
  • }??

  • 我們來分析上面的代碼:使用ImprovedVector類對象的內(nèi)置鎖,保證了contains()和add()方法的原子性,由于ImprovedVector類對象的內(nèi)置鎖也就是Vector類對象的內(nèi)置鎖(即add()方法和contains()方法的鎖),這樣有保證了add()方法和contains()方法的可見性,可以達(dá)到預(yù)期效果。?

    第三種方法舉例:?

    Java代碼??
  • (錯誤的實現(xiàn))??
  • public?class?ImprovedList<T>{??
  • ????public?List<T>?list=Collections.synchronizedList(new?ArrayList<T>());??
  • ????public?synchronized?boolean?putIfAbsent(T?x){??
  • ????????boolean?flag=list.contains(x);??
  • ????????if(!flag)??
  • ?????????????list.add(x);??
  • ????????return?!flag;??
  • ????}??
  • }??

  • 上面的例子是一個錯誤的例子,我們來分析下:首先,synchronized保證了list.contains()方法和list.add()方法的原子性,假設(shè)現(xiàn)在有一個類對象在執(zhí)行putIfAbsent()方法,而且即將執(zhí)行(還沒執(zhí)行)list.add(2)方法,此時,有另外一個線程搶先執(zhí)行了list.add(2)方法,該線程執(zhí)行完畢之后,釋放了list的鎖,接著即將執(zhí)行(還沒執(zhí)行)list.add(2)方法開始得到CPU并執(zhí)行。瞧,這個過程中,數(shù)字2被添加了2次。就是說,上面的代碼中僅僅保證了contains()方法和add()方法的原子性,以及對對list引用操作的互斥性,并沒有保證list.add()方法的可見性。?
    仔細(xì)想想,問題出在putIfAbsent()方法的鎖與list對象的鎖不是同一個,putIfAbsent()方法的鎖是ImprovedList類的鎖,而list.add()方法的鎖是Collections.synchronizedList()使用的鎖,因此將上面的代碼改成:?

    Java代碼??
  • (正確的實現(xiàn))??
  • public?class?ImprovedList<T>{??
  • ????public?List<T>?list=Collections.synchronizedList(new?ArrayList<T>());??
  • ????public?synchronized?boolean?putIfAbsent(T?x){??
  • ????????????synchronized(list){??
  • ????????????boolean?flag=list.contains(x);??
  • ????????????if(!flag)??
  • ?????????????????list.add(x);??
  • ????????????return?!flag;??
  • ????????}??
  • ????}??
  • }??


  • 第四種方法舉例:?

    Java代碼??
  • public?class?ImprovedList<T>?implements?List<T>{??
  • ????private?final?List<T>?list;??
  • ????public?ImprovedList(List<T>?list){??
  • ?????????this.list=list;??
  • ????}??
  • ????public?synchronized?boolean?putIfAbsent(T?x){??
  • ????????????boolean?flag=list.contains(x);??
  • ????????????if(!flag)??
  • ?????????????????list.add(x);??
  • ????????????return?!flag;??
  • ????????}??
  • ????}??
  • ????...實現(xiàn)List<T>接口中的其他方法??
  • }??

  • 乍一看發(fā)現(xiàn),上面的代碼在安全性方面好像弱了好多, putIfAbsent(T x)方法中的fianl變量list可能連線程安全類都不是,但是對于上面的代碼,我們有個假設(shè)(當(dāng)某個鏈表對象在傳遞給ImprovedList的構(gòu)造函數(shù)之后,客戶代碼再也不會使用這個對象,而是使用與其對應(yīng)的ImprovedList對象),有了這個假設(shè)前提,上面的代碼就是線程安全的了。?

    上面就是JAVA并發(fā)編程中,在一個已有的線程安全類的基礎(chǔ)上添加同步函數(shù)的4個方法。?


    本文轉(zhuǎn)自農(nóng)夫山泉別墅博客園博客,原文鏈接:http://www.cnblogs.com/yaowen/p/6294808.html,如需轉(zhuǎn)載請自行聯(lián)系原作者

    總結(jié)

    以上是生活随笔為你收集整理的JAVA并发-为现有的线程安全类添加原子方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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