小编典典

Java是否隐式通知等待线程?

java

我写了一个永远不会停止的测试应用程序。它发出t.wait()t是一个Thread对象),但是我从不打电话通知。为什么此代码结束?尽管主线程在上同步t,但生成的线程仍在运行,因此不会锁定该对象。

public class ThreadWait {
    public static void main(String sArgs[]) throws InterruptedException {
        System.out.println("hello");
        Thread t = new MyThread();
        synchronized (t) {
            t.start();
            Thread.sleep(5000);
            t.wait();
            java.lang.System.out.println("main done");
        }
    }
}

class MyThread extends Thread {
    public void run() {
        for (int i = 1; i <= 5; i++) {
            java.lang.System.out.println("" + i);
            try {
                Thread.sleep(500);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }
}

结果是主线程等待5秒钟,在此期间工作人员提供其输出。然后,在5秒钟后,程序退出。t.wait()不等。如果主线程在5秒钟内没有进入睡眠状态(对此行进行了注释),则t.wait()实际上将等到工作人员完成操作。当然,join()这里是一种使用方法,但是,出乎意料的是,wait()它与做相同的事情join()。为什么?

也许JVM看到,由于仅运行一个线程,因此没有机会通知主线程并解决死锁。如果是这样,是否有文件记载的功能?

我正在Windows XP,Java 6上进行测试。


阅读 209

收藏
2020-10-15

共1个答案

小编典典

您正在等待Thread-,虽然大多数对象 都没有 隐式通知,Thread但线程终止时会通知一个对象。它记载的地方(我在寻找它…),你应该
使用wait/ notifyThread对象,做为所内部完成。

这是一个很好的例子,说明为什么最佳实践是使用“私有”对象进行同步(和等待/通知)- 只有 您的代码才知道这一点。我通常使用类似:

private final Object lock = new Object();

(不过,总的来说,如果可以的话,使用java.util.concurrent提供的一些更高层次的抽象会更干净。如注释中所述,实现Runnable而不是扩展Thread自己也是一个好主意。)

2020-10-15