在Java中的main()内的Thread实例上运行wait()

sof*_*ver 8 java multithreading synchronized wait

我在java.lang.Object中使用wait()的定时版本,并观察到它在两种不同的场景中的行为不同.

场景1:在Thread中使用run()的默认定义

public static void main (String[] args) throws InterruptedException {
    Thread t = new Thread();    
    t.start();
    System.out.print("X");
    synchronized(t) { t.wait(10000);}
    System.out.print("Y");
}
Run Code Online (Sandbox Code Playgroud)

关于scenario1的问题:我遇到了X和Y之间的延迟.这是因为我从main调用wait()(即使在t上)因此正在使用主线程的调用堆栈,而不是第二个线程?

场景2:动态 子类化线程以覆盖run()以打印内容.

public static void main (String[] args) throws InterruptedException {
     Thread t = new Thread() {public void run() 
                     {System.out.print("I am the second thread.");}};
     t.start();
     System.out.print("X");
     synchronized(t) { t.wait(10000);}
     System.out.print("Y");
}
Run Code Online (Sandbox Code Playgroud)

关于场景2的问题:我没有遇到任何延迟!是什么改变只是因为我已经覆盖了run()?现在,每次我运行该程序时,它立即打印出"XI am the second thread.Y",无论如何都没有任何延迟!wait()的效果在哪里消失了?

Con*_*Del 7

实际上你已经遇到了为什么你不应该调用wait或notify(All)在线程上(参见JavaDocs for Thread).在内部,Thread使用wait和notifyAll来实现Thread.join(),所以在第二种情况下发生的是线程进入等待,但随后另一个线程死掉并调用notifyAll(),它唤醒你的主线程.

使用Thread.sleep,如果你只是想等待经过的时间,使用Thread.join,如果你真的想等待线程终止.此外,阅读JavaDoc中Object的正确使用wait,notify以及notifyAll.

javaDoc:

public final void join(long millis)
                throws InterruptedException
Run Code Online (Sandbox Code Playgroud)

此线程最多等待毫秒毫秒.超时为0意味着永远等待.此实现使用this.wait调用this.isAlive的循环.当一个线程终止时,将调用this.notifyAll方法.建议应用程序不要在Thread实例上使用wait,notify或notifyAll.


Nat*_*hes 1

关于线程完成如何发送notifyAll的解释是相关且正确的,我的+1。我将尝试添加一些关于为什么这是相关的信息。

你打电话时

synchronized(t) { t.wait(10000);}
Run Code Online (Sandbox Code Playgroud)

在主线程中,是主线程在进行等待。t是主线程正在等待的监视器。您认为这应该使您的t线程休眠的期望是错误的。

这里的监视器(被锁定的共享对象,恰好是t)用于在不同线程之间进行通信,一个线程在监视器上调用notifyAll,并且在监视器上等待的其他线程接收通知。您可以将监视器视为共享通信点。

在您的第一个示例中,线程 t 立即启动并完成(因为它没有任何事情可做)。线程在主线程开始等待之前完成并发送通知,因此您会看到等待超时之前的延迟。

在第二个示例中,线程 t 有一些内容要打印,它与主线程之间存在竞争条件。这是一场混战,首先发生什么取决于时机的意外。您看到的是,线程t现在必须向控制台打印一行,因此它设法保持足够长的忙碌状态,以便在主线程开始等待时它仍然处于活动状态,从而允许主线程在以下情况下接收通知: t 完成,导致主线程缩短其等待时间。