在等待另一个线程时将当前线程置于休眠状态

时间:2013-05-01 06:39:46

标签: java multithreading wait notify

在我的应用程序中的某个时刻,我想让我的主线程(即,当前正在执行的线程)暂停一段时间或者直到后台完成(并唤醒它),以先到者为准。

这是我所做的(我认为可行,但没有)

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

(部分)stacktrace:

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 个答案:

答案 0 :(得分:4)

为了能够调用notify(),您需要在同一个对象上进行同步。

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

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

答案 1 :(得分:2)

首先,不要wait个对象上使用notifyThread。这被用作内部信令通道,因此您的代码最终会混淆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建议的那样。

答案 2 :(得分:1)

您正在为wait()notifyAll()使用两个不同的对象:主线程在主线程上等待,而后台线程在后台线程上通知。您应该为两个调用使用共享的最终对象。您还应该在此共享对象的同步块中等待并通知,如这两种方法的javadoc中所述。并且只应退出等待状态,其中一些条件已经改变,以避免虚假的唤醒,如javadoc中所述。

但是wait()和notifyAll()太低级,太难以正确使用。您应该使用更高级别的抽象,例如信号量。

答案 3 :(得分:0)

如您所希望put the current thread to sleep while waiting for another thread,您现在的表现方式并不适用于wait and notifiy方法。

这些方法适用于同步对象而非线程。

对于线程,您应该使用加入方法Check Out

相关问题