我有一个类,它将启动一个具有无限循环的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");
}
}
Runnable类:
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()函数,Exception就会消失,但输出仍然相同。
编辑:我刚注意到,如果我对行myRunnable.shutdown();
发表评论并继续使用myThread.join();
行,即使我没有停止该线程,我仍然会得到异常。这是为什么?是因为Tread和Runnable是两个不同的东西吗?如果是这样,那么如何停止Runnable并等待其完成?
答案 0 :(得分:4)
在“版本2”中,您正在中断正在调用stopParser()
的线程,而不是正在执行run()
的线程。不要拨打Thread.currentThread().interrupt()
,而是使用myThread.interrupt()
。
我不知道你为什么会在“版本1”中遇到InterruptedException;你必须在其他地方打电话给Thread.currentThread().interrupt()
。只有当您检测到当前线程已被另一个线程中断但您无法立即终止该线程时,才应该这样做。