我编写了以下代码,其中start方法应该等到stop方法通知它。但是在执行期间,start方法下面的日志行被打印,虽然我已经指定它等待。下面显示的是我的start方法实现如下。
private static boolean stopThread = false;
public static void start(String[] args) {
startThread();
synchronized (serviceThread) {
try {
while(stopThread) {
serviceThread.wait();
}
LOGGER.log(Level.INFO, "Thread: Just after wait method");
} catch (InterruptedException e) {
LOGGER.log(Level.INFO, "'Wait' interrupted: " + e.getMessage());
}
}
}
下面显示的是我的停止方法实现。
public static void stop(String[] args) {
if (serviceThread != null) {
LOGGER.log(Level.INFO, "Stopping the thread");
serviceThread.interrupt();
LOGGER.log(Level.INFO, "Thread: Successfully interrupted");
synchronized (serviceThread) {
LOGGER.log(Level.INFO, "About to notify");
serviceThread.notify();
stopThread = true;
}
stopPlugins();
kubeLogManager.closeLogger();
messageBus.terminateMessageBus();
System.exit(0);
} else {
LOGGER.log(Level.INFO, "No thread to interrupt");
}
}
为什么即使在调用stop方法之前,wait方法下面的日志行也会打印出来?请指教。
答案 0 :(得分:1)
请参阅Object.wait的文档:
https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#wait()
中断和虚假唤醒是可能的,并且这个方法应该总是在循环中使用:
synchronized (obj) { while (<condition does not hold>) obj.wait(); ... // Perform action appropriate to condition }
您应该使用变量来指示何时调用stop()
,并在调用notify()
之前设置它。此外,使用notifyAll()
更安全,因为如果你以某种方式让另一个线程等待对象,它仍然有效。