1. 程式人生 > >Vector是執行緒安全的

Vector是執行緒安全的

上次被問到,vector是執行緒安全的,一直不知道是為什麼,看了csdn上一篇提問(http://bbs.csdn.net/topics/320059353),簡要總結一下:

Vector<String> test = Vector<String>(); ....... ....... for (i = 0; i < test.size(); i++) { /////////////////在此處當前執行緒時間片到期 ///執行緒重新獲取時間片,但test內元素有可能已經被其他執行緒修改 System.out.println(test.get(i)); } 1.Vector中的方法是同步的。Vector的所有操作方法都被同步了,既然被同步了,多個執行緒就不可能同時訪問vector中的資料,只能一個一個地訪問,所以不會出現資料混亂的情況,所以是執行緒安全的。
2.同一個vector,A執行緒訪問的時候,B執行緒不能訪問而掛起(等待狀態),等A釋放對vector的鎖以後B才能訪問。而同一個List可以被多個執行緒同時訪問 。 3.Vector所謂的執行緒安全是指呼叫Vector類的成員方法時,其他執行緒不能再訪問該Vector物件。但是在呼叫兩個Vector成員方法時,當前執行緒有可能再完成第一個方法後時間片到期,這時其他執行緒可以訪問該Vector物件,造成呼叫第二個成員方法的結果可能與預想結果不同。這時為保證執行緒安全,需要加synchronized。 問題引導到SB的執行緒安全問題: A.
synchronized(map){
Object value = map.get(key); if(value == null) { value = new Object(); map.put(key,value); } return value;}

上面程式碼中 map 即使是執行緒安全的也沒有用,如果不在外面加synchronized,map.get和map.put之間的程式碼片段都有可能被其他執行緒重入,可能出現同一個key對應多個value.

另一方面,其他情況下可能不需要執行緒同步,這時候所謂執行緒安全就是多餘了。StringBuffer就是個典型的例子,我還從來沒見過有人把StringBuffer用在多執行緒中。顯然SUN也認識到了這點,重寫了一個功能相同的但不支援執行緒安全的StringBuilder,後期的編譯器中把String相加的程式碼都用StringBuilder實現。

B.當兩個執行緒同時執行sb.append()操作時,StringBuffer可以保證2個操作都被執行,不會其中一個被另一個沖掉,因為append()方法是synchronized的,這樣2個append是先後執行的。但是StringBuilder則有可能發生其中一個操作被另一個沖掉的情況,因為2個執行緒的append()方法不需要獲得鎖。我覺得,所謂的執行緒安全,大概也就只能做到這點了,保證StringBuffer裡面的方法本身不會因為同步執行而發生錯誤的結果。但是由於我們的應用中,如果需要控制同步,肯定不止在這個層次,否則,一般都是不需要同步的(區域性變數),因此才誕生了StringBuilder方法。 vector執行緒安全的原因已知,但如何應用同步,同時其餘的執行緒安全原因,也需要抽時間歸納一下