線程間的相互作用
線程間的相互作用:線程之間需要一些協調通信,來共同完成一件任務。
Object類中相關的方法有兩個notify方法和三個wait方法:
Object (Java Platform SE 7 )
因為wait和notify方法定義在Object類中,因此會被所有的類所繼承。
這些方法都是final的,即它們都是不能被重寫的,不能通過子類覆寫去改變它們的行為。
wait()方法
wait()方法使得當前線程必須要等待,等到另外一個線程調用notify()或者notifyAll()方法。
當前的線程必須擁有當前對象的monitor,也即lock,就是鎖。
線程調用wait()方法,釋放它對鎖的擁有權,然后等待另外的線程來通知它(通知的方式是notify()或者notifyAll()方法),這樣它才能重新獲得鎖的擁有權和恢復執行。
要確保調用wait()方法的時候擁有鎖,即,wait()方法的調用必須放在synchronized方法或synchronized塊中。
一個小比較:
當線程調用了wait()方法時,它會釋放掉對象的鎖。
另一個會導致線程暫停的方法:Thread.sleep(),它會導致線程睡眠指定的毫秒數,但線程在睡眠的過程中是不會釋放掉對象的鎖的。
notify()方法
notify()方法會喚醒一個等待當前對象的鎖的線程。
如果多個線程在等待,它們中的一個將會選擇被喚醒。這種選擇是隨意的,和具體實現有關。(線程等待一個對象的鎖是由于調用了wait方法中的一個)。
被喚醒的線程是不能被執行的,需要等到當前線程放棄這個對象的鎖。
被喚醒的線程將和其他線程以通常的方式進行競爭,來獲得對象的鎖。也就是說,被喚醒的線程并沒有什么優先權,也沒有什么劣勢,對象的下一個線程還是需要通過一般性的競爭。
notify()方法應該是被擁有對象的鎖的線程所調用。
(This method should only be called by a thread that is the owner of this object's monitor.)
換句話說,和wait()方法一樣,notify方法調用必須放在synchronized方法或synchronized塊中。
wait()和notify()方法要求在調用時線程已經獲得了對象的鎖,因此對這兩個方法的調用需要放在synchronized方法或synchronized塊中。
一個線程變為一個對象的鎖的擁有者是通過下列三種方法:
1.執行這個對象的synchronized實例方法。
2.執行這個對象的synchronized語句塊。這個語句塊鎖的是這個對象。
3.對于Class類的對象,執行那個類的synchronized、static方法。
程序實例
利用兩個線程,對一個整形成員變量進行變化,一個對其增加,一個對其減少,利用線程間的通信,實現該整形變量0101這樣交替的變更。
public class NumberHolder
{
private int number;
public synchronized void increase()
{
if