Java多執行緒的安全問題(02)

2021-08-26 17:47:46 字數 2024 閱讀 5602

要求:在電影院有三個視窗同時賣電影票(50張)。啟動3條執行緒,每1條執行緒代表乙個售票視窗。

1)定義賣票的執行緒。

class saleticketthread extends thread 

@override

public void run() else

} }}

因為多個視窗共享著這50張票,所以設定num成員屬性為靜態static。

2)啟動三條執行緒同時進行賣票。

public class demo 

}

執行上面程式發現存在以下問題:

1)一張電影票被賣出了多張;

2)票賣光後,還可以繼續賣;

存現上面問題的原因,是因為多執行緒的安全問題導致的。如果多線執行緒同時共享著同乙個資源,而且訪問資源的任務**有多行的時候,就有可能會出現執行緒安全問題。上面例子就是因為多個執行緒共享同乙個num變數,而且執行賣票的**有多行,所以就出現了執行緒安全問題。如果出現了執行緒安全問題,那麼就會導致共享資源的資料發生錯亂,從而出現結果不一致的情況。

同步**塊可以保證在同乙個時間片內只有乙個執行緒執行同步**塊中的**。

synchronized (鎖物件)
鎖物件可以是任意物件。但是,必須要保證多個執行緒可以共享同乙個鎖物件。所以,只要保證多個執行緒共享同乙個物件,那麼該物件就可以作為鎖。

synchronized ("鎖")  else 

}}

上面程式使用了字串常量作為鎖物件。

訪問修飾符 synchronized 返回值型別 函式名(形參列表)
同步函式就是在函式返回值型別前面加上synchronized關鍵字即可。

注意:同步函式也有鎖物件。而同步函式的鎖物件就是this。

@override

public synchronized void run() else

}}

執行上面程式發現,執行緒安全問題仍然存在,問題沒有被解決(見下圖)。

因為同步函式的鎖物件是this,也就是當前的執行緒物件。也就是說,如果啟用多條執行緒進行賣票的時候,它們並不是共享同乙個鎖物件。那麼,是不是就不能夠使用同步函式解決上面問題呢?答案是可以的。但是需要使用另外一種建立執行緒的方式。

第一步:定義乙個類,實現runnable介面;

第二步:重寫runnable介面的run方法, 把需要實現的任務**定義在該方法中;

第三步:建立該類物件;

第四步:建立thread物件,然後把上面建立的物件傳入到建構函式中;

第五步:呼叫thread物件的start方法啟動執行緒;

class myrunnable implements runnable 	}	

}public class demo1

}

注意:實現runnable介面的物件不是執行緒物件。之所以在建立thread物件時候傳入乙個runnable物件,是因為thread物件需要借用runnable物件的run方法執行任務**。

class saletickettask implements runnable  else 

} }}public class demo

}

執行上面程式發現,之前出現的同步安全問題解決了。

上面程式之所以能夠在run方法上使用synchronized,是因為同步函式的鎖物件是this,即runnable物件,t1、t2、t3執行緒都是共享同乙個runnable物件。

iOS多執行緒 02 多執行緒的安全問題

1塊資源可能會被多個執行緒共享,也就是多個執行緒可能會訪問同一塊資源 比如多個執行緒訪問同乙個物件 同乙個變數 同乙個檔案 蘋果不建議使用互斥鎖,因為太消耗效能 1 互斥鎖使用格式 synchronized 鎖物件 注意 鎖定1份 只用1把鎖,用多把鎖是無效的 2 互斥鎖的優缺點 優點 能有效防止因...

Java多執行緒4 安全問題

這樣的執行機制就可能會導致多執行緒的安全問題 1.多個執行緒操作共享資料 2.在乙個執行緒中有多行 操作共享資料 改變共享資料 解決思路 乙個執行緒在執行執行緒任務的時候將多條操作共享資料的 一起執行,在執行過程中不允許其他執行緒執行 體現 package thread class tickets ...

Java 多執行緒存在的安全問題

存在的問題 當num 1時,假如執行緒t1此時拿到cpu,執行任務 在判斷if語句條件剛剛結束時,也就是還沒來得及執行輸出語句,cpu被t2搶走了,此時num依然等於1,那麼if條件通過,在執行過程中,依然可能被其他執行緒搶走cpu而進入阻塞狀態,最後有可能賣出0,1,2這種票,這就是多執行緒存在的...