我有一个类将启动一个无限循环的 Runnable。在某些时候,我想关闭程序,并且我想以一种干净的方式来完成它(例如,确保在执行结束时线程将刷新一些缓冲区以输出文件等)。我该怎么做?
注意:在注释中我写了//Version 1
和//Version 2
。那是因为我尝试了两个版本,但都不起作用,我不断收到 InterruptedException。
主类:
public class MainClass {
private static Thread myThread;
private static MyRunnable myRunnable;
private static Logger logger;
public static void main( String[] args ) {
...
myRunnable = new MyRunnable(logger);
myThread = new Thread(myRunnable);
myThread.start();
...
}
private static void shutDown() {
logger.debug("Shut down everything.");
if(myRunnable != null){
myRunnable.shutdown();
try {
myThread.join();
logger.debug("Runnable Stopped");
} catch (InterruptedException e) { // Always failing here
e.printStackTrace();
}
}
// Now stop logger and other things
logger.debug("Shutdown other stuff");
...
logger.debug("Shutdown logger");
Configurator.shutdown((LoggerContext)LogManager.getContext());
System.out.println("Done");
}
}
可运行类:
public class MyRunnable implements Runnable {
private AtomicBoolean stop = new AtomicBoolean(false); // Version 1
public boolean isStopped() {
return stop.get(); // Version 1
return Thread.currentThread().isInterrupted(); // Version 2
}
public void shutdown() {
logger.debug("Stopping my runnable");
stop.set(true); // Version 1
Thread.currentThread().interrupt(); // Version 2
}
@Override
public void run() {
try{
while(!isStopped()) {
// Do things
}
logger.debug("Exiting from infinite loop");
} catch(Exception e){
logger.error("Exception! " + e.getMessage());
} finally {
logger.debug("Entering in finally part");
// Flush buffer, commit to database, ... close stuff
}
}
}
但是 shutdown 函数的输出始终是相同的:
Shut down everything.
java.lang.InterruptedException
at java.lang.Object.wait(Native Method)
at java.lang.Thread.join(Thread.java:1260)
at java.lang.Thread.join(Thread.java:1334)
at com.my.packageName.MainClass.shutDown(MainClass.java:374)
Shutdown other stuff
Shutdown logger
Done
如果我删除 join() 函数,异常就会消失,但输出仍然相同。
编辑:我刚刚注意到,如果我注释 myRunnable.shutdown();
行并继续使用 myThread.join();
行,我仍然即使我没有停止该线程,也会得到异常。这是为什么?是因为 Tread 和 Runnable 是两个独立的东西吗?如果是这样,那么我如何停止 Runnable 并等待其完成?
最佳答案
在“版本 2”中,您正在中断正在调用 stopParser()
的线程,而不是正在执行 run()
的线程。不要调用 Thread.currentThread().interrupt()
,而是使用 myThread.interrupt()
。
我不知道为什么你会在“版本 1”中收到 InterruptedException;您必须在其他地方调用 Thread.currentThread().interrupt() 。仅当您检测到当前线程已被另一个线程中断但又无法立即终止该线程时才应执行此操作。
关于Java 等待可运行完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33292052/