關於線程安全和非線程安全的幾個問題

前記:全篇以java多線程為例

1.線程安全與不安全

線程安全:就是當多線程訪問時,採用加鎖的機制;即當一個線程訪問該類的某個數據時,會對這個數據進行保護,其他線程不能對其訪問,直到該線程存取操作完成之後,其他線程才允許訪問。

線程不安全:就是不提供數據訪問時的數據保護,多個線程能夠同時操作某個數據,從而出現數據不一致或者數據汙染的情況。

對於線程不安全的問題,一般會使用synchronized關鍵字加鎖,進行排他性控制(同步控制)。

2.線程安全工作原理

由於多線程共享同一進程的存儲空間,jvm中有個main memory對象,每個線程也有自己的working memory,一個線程對於一個變量variable進行操作的時候,都需要在自己的working memory裡創建一個copy,操作完後,再寫入main memory。當多個線程操作同一個變量variable,就可能出現互相競爭,操作順序不可控,導致不可預知的結果。而是用了synchronized關鍵字就在在代碼段裡定義了一個同步訪問控制塊,在這個塊上建立了一個monitor監控對象,然後通過這個加鎖,解鎖來實現同步控制。

例如:

class TestMain2 extends Thread{
private static AppleList appleList= new AppleList();
@Override
public void run(){
synchronized (appleList){//加鎖
if (appleList.isFull()){ //操作非線程安全的集合對象
System.out.println(this.getId() + ",籃子已滿,無法裝填,可以歇一歇了" );
}
else{
appleList.pushApple(); //操作非線程安全的集合對象 System.out.println(this.getId() + ",生產了一個,c="+ appleList.getCount() );
}
}//自動解鎖
}
}

3.線程安全thread-safe的集合對象:

Vector,HashTable,StringBuffer

4.非線程安全集合對象

ArryList,LinkedList,HashMap,HashSet,TreeMap,StringBulider


分享到:


相關文章: