我想等到线程进入等待状态。我一直在尝试使用join(见下文),但它没有用。怎么做到这一点?
public Test() {
System.out.print("Started");
Thread thread = new Thread(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (Test.class) {
try {
Test.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print("Done");
}
完成从未打印过。
答案 0 :(得分:1)
你的主线程没有超越join()
,因为第二个线程永远不会结束。第二个帖子永远不会结束,因为它正在Test.class
等待通知,但没有人通知它。
如果希望主线程在第二个线程到达Test.class.wait();
行时继续执行,则需要为此同步引入另一个监视器。主线程必须在此监视器上等待,并且第二个线程必须在准备切换到等待状态时通知它:
System.out.println("Started");
final Object monitor = new Object();
Thread thread = new Thread(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Finished");
synchronized (monitor) {
monitor.notify(); // Notify the main thread
}
synchronized (Test.class) {
try {
Test.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread.start();
synchronized (monitor) {
try {
monitor.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Done");
这段代码可行,但看起来有点难看。它还会留下一个挂起的线程,阻止程序正常终止。如果您希望此线程完成,则需要有人致电Test.class.notify()
。
从您的问题中不清楚您一般会尝试实现的目标。如果你想要产生一个线程并等到它完成,你就不需要那些wait()
和notify()
,只需使用join()
:
System.out.println("Started");
Thread thread = new Thread(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Finished");
});
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Done");
还有一件事:在构造函数中创建和启动线程是一个非常糟糕的主意。为此使用单独的方法(如initialize()
)。