Java 等待可运行完成

标签 java multithreading 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
        }
    }
}

但是 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/

相关文章:

Java可选类方法无法解析

java - 确定 Java ThreadPoolExecutor 中执行任务的优先级

python - 为了提高我的 python 程序的速度,我应该生成一个单独的线程还是一个单独的进程来进行日志记录?

Java Handler Post Delayed 任务不是准确的计时器

java - 具有不同字母长度的替换密码

java - 覆盖jfreechart绘制点的位置而不覆盖drawItem

java - 如何使用随添加的每个子项而递增的 key 将子项添加到 Firebase 数据库?

multithreading - Java多线程两个生产者和1个消费者问题

java - 我创建了一个线程吗?

java - 为什么它不起作用? (通过java中的Runnable发送函数作为参数)