2013-05-01 128 views
0

在我的應用程序中的某個時刻,我想讓我的主線程(即當前正在執行的線程)休眠一段時間或直到背景完成(和喚醒它),以先到者爲準。當前線程在等待另一個線程時睡眠

這裏是我做的(我想會的工作,但沒有)

public static void main(String args[]) 
{ 
    // .... other stuff ... 

    // show a splash screen 
    // just think of this as an image 
    showPlashScreen(): 
    new Thread(new Runnable() 
    { 
      public void run() 
      { 
       // do some work here 

       // notify everyone after the work is done 
       Thread.currentThread().notifyAll(); 
      } 
    }).start(); 

    // now make the current thread to wait for the background 
    // or for at most 1000 
    Thread.currentThread().wait(1000); 
    disposeSplashScreen(); 

    // ... other stuff .... 
} 

執行此,我不斷收到java.lang.IllegalMonitorStateException

(部分)堆棧跟蹤:

Caused by: java.lang.IllegalMonitorStateException 
    at java.lang.Object.wait(Native Method) 

.... <cut> .... 

Exception in thread "Thread-7" java.lang.IllegalMonitorStateException 
    at java.lang.Object.notifyAll(Native Method) 

回答

4

爲了能夠調用notify(),您需要在同一個對象上進行同步。

synchronized (someObject) { 
    someObject.wait(); 
} 

/* different thread/object */ 
synchronized (someObject) { 
    someObject.notify(); 
} 
+0

這適用於我!但你會介意解釋它是如何工作的嗎?所以在第一個同步塊中,當執行'someObject.wait()'時,當前線程會進入休眠狀態(什麼也不做),對吧?這意味着同步塊尚未完成執行。結果,'someObject'將被當前線程(永遠)激活!第二個同步塊如何獲得'someObject',以便它可以調用'notify'? (我很確定我上面有什麼問題,請你指出一下嗎?謝謝!) – 2013-05-01 07:30:48

+1

這很簡單。只要monitor('someObject')所有者線程到達wait方法,它就停止成爲所有者,鎖釋放,線程開始休眠,直到調用notify方法。 – SeniorJD 2013-05-01 07:43:46

2

首先,不要Thread上使用waitnotify對象。這被用作內部信令通道,所以你的代碼最終會混淆JRE代碼,反之亦然。

其次,它不工作的原因之一是你的主線程正在等待自己,後臺線程正在通知自己 - 這些是不同的對象!

第三,要使用notify()wait(),您需要先在顯示器上進行同步。此外,對於wait,您通常會使用循環來檢查條件,以處理虛假喚醒。

第四,如果你真的在等待一個線程年底,你可以用join代替:

Thread thread = new Thread(new Runnable() 
{ 
    @Override public void run() 
    { 
     // do some work here 
    } 
}); 
thread.start(); 

// Do something else 

thread.join(1000); 

(不幸的是join並不表示它是否返回由於超時或線程完成 - 但你可以在之後檢查線程狀態。)

或者,使用java.util.concurrent中的更高級別的構造之一,而不是像JB Nizet所建議的那樣,它們通常較少繁瑣。

+0

請參閱[此鏈接](http://stackoverflow.com/questions/16219111/cant-transparent-and-undecorated-jframe-in-jdk7-when-enabling-nimbus) – Azad 2013-05-01 06:58:09

1

您對wait()notifyAll()使用了兩個不同的對象:主線程在主線程上等待,而後臺線程在後臺線程上通知。您應該爲這兩個調用使用共享的最終對象。您還應該等待並通知此共享對象的同步塊,如這兩種方法的javadoc中所述。正如javadoc中所解釋的那樣,只有退出等待狀態才能改變狀態,以避免虛假喚醒。

但wait()和notifyAll()太低級別,太難以正確使用。您應該像Semaphore那樣使用更高級別的抽象。

0

當你想put the current thread to sleep while waiting for another thread,你現在的樣子做,到現在爲止並不意味着同樣的事情,即wait and notifiy方法。

這些方法的目的是用於同步對象不適用於線程。

對於線程,您應該使用連接方法Check Out