Java 等待可运行完成

Java wait for runnable to finish

我有一个 class 将启动一个带有无限循环的 Runnable。在某些时候,我想关闭程序,并且我想以一种干净的方式进行(例如,确保在执行结束时线程将刷新一些缓冲区以输出文件等)。我该怎么做?

注意:在评论中我写了 // Version 1// Version 2。那是因为我尝试了两个版本并且 none 它们都有效,我不断收到 InterruptedException。

主要Class:

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");
    }
}

可运行class:

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并等待它完成?

在 "version 2" 中,您正在中断调用 stopParser() 的线程,而不是正在执行 run() 的线程。不要调用 Thread.currentThread().interrupt(),而是使用 myThread.interrupt().

我不知道你为什么会在 "version 1" 中得到 InterruptedException;您一定是在其他地方调用 Thread.currentThread().interrupt()。只有当您检测到当前线程已被另一个线程中断但您不能立即终止该线程时,您才应该这样做。