Ява ждать для Runnable, чтобы закончить
У меня есть класс, который будет запускать 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
}
}
}
Но вывод функции выключения всегда один и тот же:
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 (), исключение исчезает, но вывод остается тем же самым.
EDIT: я только что заметил, что если я комментирую строку myRunnable.shutdown();
и продолжаю линию myThread.join();
, я все равно получаю исключение, даже если я не останавливаю этот поток. Почему это так? Не потому ли, что беговая дорожка и беговая дорожка-это две разные вещи? Если это так, то как я могу остановить бегучего и ждать его завершения?
1 ответ:
В "версии 2" вы прерываете поток, который вызывает
stopParser()
, а не поток, который выполняетrun()
. Вместо вызоваThread.currentThread().interrupt()
ИспользуйтеmyThread.interrupt()
.Я не знаю, почему вы получили бы InterruptedException в "версии 1"; Вы, должно быть, вызываете
Thread.currentThread().interrupt()
где-то еще. Вы должны сделать это только тогда, когда вы обнаружили, что текущий поток был прерван другим потоком, но вы не можете завершить поток немедленно.