java - 这是停止执行任务的正确方法吗

标签 java multithreading

我遇到了停止执行任务的代码。

private final ExecutorService executor = Executors.newSingleThreadExecutor();

public void stop() {
    executor.shutdownNow();
    try {
        executor.awaitTermination(100, TimeUnit.DAYS);
    } catch (InterruptedException ex) {
        log.error(null, ex);
    }
}


public Runnable getRunnable() {
    return new Runnable() {
        public void run() {
            while (!Thread.currentThread().isInterrupted()) {
                // What if inside fun(), someone try to clear the interrupt flag?
                // Say, through Thread.interrupted(). We will stuck in this loop
                // forever.
                fun();
            }
        }
    };
}

我意识到,Runnable 可能会处于永远循环中,因为

  1. 未知的fun可能Thread.sleep,清除中断标志并忽略InterruptedException
  2. 未知fun可能Thread.interrupted,清除中断标志。

我想知道,下面的方法是修复代码的正确方法吗?

private final ExecutorService executor = Executors.newSingleThreadExecutor();
private volatile boolean flag = true;

public void stop() {
    flag = false;
    executor.shutdownNow();
    try {
        executor.awaitTermination(100, TimeUnit.DAYS);
    } catch (InterruptedException ex) {
        log.error(null, ex);
    }
}


public Runnable getRunnable() {
    return new Runnable() {
        public void run() {
            while (flag && !Thread.currentThread().isInterrupted()) {
                // What if inside fun(), someone try to clear the interrupt flag?
                // Say, through Thread.interrupted(). We will stuck in this loop
                // forever.
                fun();
            }
        }
    };
}

最佳答案

没有办法确保未知函数结束。如果 fun 如下所示,您将无法在不关闭应用程序的情况下终止它。

  void fun(){
     while(true){
        try{
           ...
        }catch(Throwable th){

        }
     }
  } 

向 Runnable 添加标志在这里不会有帮助,因为 fun() 永远不会退出。一些旨在终止线程的方法(例如 Thread.destroy())已被弃用,因为它会使程序处于未知状态。

只有两种方法可以确保函数终止:

  • 确保它遵循指定的行为。对于您来说,这将是:不要永远循环,不要清除中断标志或您自己的标志。
  • 或者,在 jvm 的单独实例中运行该函数,如果该函数没有返回而不终止主程序,您可以终止 jvm。

如果您可以控制 fun() 或知道它最终会返回,那么添加您自己的标志将是一个有效的解决方案,您应该确保它处理如您所料有中断。

关于java - 这是停止执行任务的正确方法吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4707096/

相关文章:

c# - 线程在 2 分钟后什么都不做

JavaFX : updating progress for the multiple tasks

c++ - 使用信号和线程的事件管理器

java - 无法从 Java 启动 .exe

java - 在 Java 中使用模式匹配

java - 字符更改时拆分字符串。可能的正则表达式解决方案?

objective-c - NSTask 阻塞主线程

c# - 表格以某种方式被处置

java - 离开 android 中的 Activity 后如何保留 ListView ?

java - Java 中基于正则表达式的字符串拆分