1. 程式人生 > >java線程學習之wait方法

java線程學習之wait方法

有一點 線程學習 while wait方法 意思 ted 線程 title prop

wait 等待方法是讓線程進入等待隊列,使用方法是 obj.wait(); 這樣當前線程就會暫停運行,並且進入obj的等待隊列中,稱作“線程正在obj上等待”。

如果線程想執行 wait 方法,線程必須擁有鎖。如果線程進入等待隊列,就會釋放其實例的鎖。

有兩種形式的wait方法

一種是:接受毫秒數作為參數,含義與sleep中方法裏接受參數的意思相同,都是指“在此期間暫停”,但是與sleep方法不同的是,wait 在暫停等待期間,對象鎖是釋放的,而sleep是擁抱著這把鎖;還有一點不同的是,wait方法可以通過notify,notifyAll或者等待的時間到期,都可以令此線程接著執行。(時間參數值必須大於0,如果小於0,則會拋出 IllegalArgumentException運行異常,

如果時間參數為0 ,則會一直等待下去)

在接收參數的wait方法中,有兩種分別是:

          public final void wait(long timeout) throws InterruptedException
          public final void wait(long timeout,int nanos)throws InterruptedException
技術分享圖片
 1  public final void wait(long timeout, int nanos) throws InterruptedException {
2 if (timeout < 0) { 3 throw new IllegalArgumentException("timeout value is negative"); 4 } 5 6 if (nanos < 0 || nanos > 999999) { 7 throw new IllegalArgumentException( 8 "nanosecond timeout value out of range");
9 } 10 11 if (nanos >= 500000 || (nanos != 0 && timeout == 0)) { 12 timeout++; 13 } 14 15 wait(timeout); 16 }
wait(long timeout, int nanos)在Object中的顯示

另一種是:wait 方法不接受任何參數,這種wait(),將無限等待下去,直到線程接收到nofity或者notifyAll的通知信息,才能繼續執行。

摘自JDK 的API:

在沒有被通知、中斷或超時的情況下,線程還可以喚醒一個所謂的虛假喚醒 (spurious wakeup)。雖然這種情況在實踐中很少發生,但是應用程序必須通過以下方式防止其發生,即對應該導致該線程被提醒的條件進行測試,如果不滿足該條件,則繼續等待。換句話說,等待應總是發生在循環中,如下面的示例:

synchronized (obj) {
while (<condition does not hold>)
obj.wait(timeout);
... // Perform action appropriate to condition
     }
 

如果在當前線程等待通知之前或者正在等待通知時,任何線程中斷了當前線程。在拋出此異常時,當前線程的中斷狀態 被清除,就會拋出中斷異常InterruptedException

java線程學習之wait方法