一個多線程的程式,兩個或者多個線程可能需要通路同一個資料資源。這時就必須考慮資料安全的問題,需要線程互斥或者同步。
當多個線程需要通路同一資源時,要求在一個時間段内隻能允許一個線程來操作共享資源,操作完畢後别的線程才能讀取該資源,這叫線程的互斥。我們需要使用synchronized來給共享區域加鎖,確定共享資源安全。
如果一個線程調用了某個對象的synchronized方法,它在這個方法運作完之前不會被别的線程打斷,這就是線程的同步機制。一般将共享資源放在這個同步方法内部,這樣就保證在一個線程對這個資源操作完之後别的線程才可以通路。
将共享資源放在同步方法或者同步代碼塊中可以保證一個線程對共享資源操作時不會被打斷,凡是被synchronized修飾的資源,在運作的時候系統都要給它們配置設定一個管理程式,這需要消耗一部分資源。
最後運作的結果計數器的值為300,大家可以嘗試一下把synchronized 去掉,結果可能就會改變。
在某些情況下,線程需要交替執行。比如一個線程向一個存儲單元執行存放資料,而另一個操作執行取值操作,線程間同步完成這個存取任務,需要将這些線程同步。要解決線程交替執行但是又要保證共享資源安全,這需要使用到java3個方法:wait()、notify()和nodifyall()、這3個方法是object類的成員方法,是以在任何類中都可以使用這3個方法。
傳回值
方法名
說明
public final void
wait()
使目前線程睡眠,直到其它線程進入管程喚醒它
notify()
喚醒此對象等待池中第一個調用wait()方法的線程
nodifyall()
喚醒此對象等待池中所有睡眠的線程
生産者-消費者問題是作業系統中的一個著名程序同步的問題。這個問題用線程思想表達出來就是說有一些生産線程産生資料放置在公共區,一些消費線程去提取消費資料。在這個問題中要保護公共資源的安全性,在生産者生産物資時消費線程必須等待不能打斷生産線程,當生産到一定數量時,生産線程暫停讓消費線程提取資料。我們來通過一個例子來示範這個過程: