【问题标题】:Java Concurrency - Adding a Shutdown hook before calling `ExecutorService#execute`Java 并发 - 在调用 `ExecutorService#execute` 之前添加一个 Shutdown 钩子
【发布时间】:2018-10-29 09:58:26
【问题描述】:

我有一个可运行的线程 MyDesiredRunnable,它具有以下运行:

public void run() {
    try {
        this.process();
    } catch (InterruptedException e) {
        isAlive.set(false);
    }
}

isAlive 是一个AtomicBoolean

调度器:

// Class definition bla bla bla
   private final ExecutorService exth = Executors.newSingleThreadExecutor();

public void schedule() {
    Runnable r = new MyDesiredRunnable();
    Runnable sdt = ()->{MyDesiredRunnable.isAlive.set(false);};

    Runtime.getRuntime().addShutdownHook(new Thread(sdt));
    this.exth.execute(r);
}

此调度程序将始终只有一个实例。我的问题是,“如果我在调用 execute 之前添加关闭挂钩是否重要。我从 javadocs 中可以理解的是,在命令 JVM 关闭之前不会解决关闭挂钩。此外,execute 命令也似乎没有说任何反对在之前/之后有一个关闭挂钩。只是SO上的一些ExecutorService示例甚至一些书籍在我们调用执行之后发生了关闭挂钩注册。所以我只是想知道是否有是我不理解的“Catch”。

谢谢,

【问题讨论】:

  • 与其捕获特定异常,不如在finally 块中设置false,这样只有System.exit 会阻止它被设置。
  • JVM 可以在调用 execute 之前停止,因此即使所需的可运行对象不是,也会调用关闭钩子。但由于关闭挂钩设置 AtomicBoolean(在这种情况下),这不是问题。 (如果释放仅在可运行文件中创建的资源可能会出现问题 - 可能是关闭挂钩的错误使用)
  • 我想首先添加关闭钩子的唯一好处是,万一JVM在两个语句之间精确关闭,您可以保证关闭钩子将被执行。也就是说,当 JVM 即将终止时,设置一个布尔字段还有什么意义呢?
  • @PeterLawrey 公平点!我没有心情制作try-catch-finally 设置,但是是的,你是对的。为什么不:)

标签: java multithreading executorservice


【解决方案1】:

为避免尝试检测任务是否间接运行,您可以使用线程本身。如果线程不活跃,则您的任务没有运行。

class ThreadedRunnable implements Runnable {
    volatile boolean started = false;
    volatile Thread thread;
    Runnable runnable;

    ThreadedRunnable(Runnable runnable) { this.runnable = runnable; }

    public void run() {
        thread = Thread.currentThread();
        started = true;
        try {
            runnable.run();
        } catch (Throwable t) { // don't silently discard it
            logger.error(runnable + " died", t);
        } finally {
            thread = null;
        }
    }

    public String state() { // or return an Enum
        Thread t = thread;
        return !started ? "not started" :
               t == null || !t.isAlive() ? "finished" : "running";
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-13
    • 2016-09-01
    • 2016-12-23
    • 2020-07-14
    • 2015-04-07
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    相关资源
    最近更新 更多