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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

多线程:Vector是线程安全的吗

發布時間:2025/3/21 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多线程:Vector是线程安全的吗 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

線程安全,在java的多并發編程中是重要概念,意思是,多個線程同時操作一個對象,在各種不同情況下,都不會造成不同的后果。

一個經典問題,Vector到底是不是線程安全的?

?

很多人都會回答,是,vector是線程安全的。

誠然,不止是很多IT教材上是這么寫的,就連JDK的作者寫的注釋也是這么說的。如下圖(圖為 JDK中Vector的源代碼):注釋中,紅框標記的部分寫著:如果你不需要線程安全的實現類,那就推薦你用ArrayList,而不是Vector。言外之意,就是說,Vector是線程安全的。

自己看了源碼,發現,確實很多方法都有同步關鍵字synchronized,從而保證所有的對外接口都會以 Vector對象為鎖,即,在vector內部,所有的方法都不會被多線程訪問。

但是,單個方法的原子性(注:原子性,程序的原子性即不會被線程調度機制打斷)并不能保證復合操作也具有原子性。


所以,這個問題的正確回答應該是:

雖然源代碼注釋里面說這個是線程安全的,因為確實很多方法都加上了同步關鍵字synchronized,但是對于復合操作而言,只是同步方法但并沒有解決線程安全的問題。因為在兩個原子操作之間存在間隙,在多線程環境中,完全有可能被其他線程獲得 vector的 lock 并改變其狀態。要真正達成線程安全,還需要以vector對象為鎖,來進行操作。所以,如果是這樣的話,那么用vector和ArrayList就沒有區別了,所以,不推薦使用vector。


舉個栗子:

if (!vector.contains(element))?vector.add(element);?... }



這是經典的?put-if-absent?情況,盡管 contains, add 方法都正確地同步了,但作為 vector?之外的使用環境,仍然存在??race condition: 因為雖然條件判斷?if (!vector.contains(element))與方法調用?vector.add(element);??都是原子性的操作 (atomic),但在 if 條件判斷為真后,那個用來訪問vector.contains 方法的鎖已經釋放,在即將的 vector.add?方法調用 之間有間隙,在多線程環境中,完全有可能被其他線程獲得 vector的 lock 并改變其狀態, 此時當前線程的vector.add(element);??正在等待(只不過我們不知道而已)。只有當其他線程釋放了 vector 的 lock 后,vector.add(element);?繼續,但此時它已經基于一個錯誤的假設了。

單個的方法 synchronized 了并不代表組合(compound)的方法調用具有原子性,使 compound actions? 成為線程安全的可能解決辦法之一還是離不開intrinsic lock?(這個鎖應該是 vector 的,但由 client 維護):

// Vector v = ...public? boolean putIfAbsent(E x) { synchronized(v) {?boolean absent = !contains(x);?if (absent) {?add(x); }? }return absent;?}

?

總結

以上是生活随笔為你收集整理的多线程:Vector是线程安全的吗的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。