【问题标题】:How to set ScheduledExecutorService to end when user quits program?用户退出程序时如何设置 ScheduledExecutorService 结束?
【发布时间】:2018-05-10 13:58:16
【问题描述】:

我有一个 ScheduledExecutorService,我将 Runnable 传递给它。如果线程所针对的 Enemy 对象死掉了,我会以 .shutDown() 结束线程,这样可以正常工作。但是,如果用户退出程序,线程仍然运行。发生这种情况时如何关闭它?

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    scheduler.scheduleAtFixedRate(runnable, 2,2, TimeUnit.SECONDS);


Runnable runnable = new Runnable() {
    @Override
    public void run() {
        System.out.println("SHOOT");
    }
};

现在我正在从 Application 的 Main 中覆盖 stop()method。

@Override
public void stop() throws Exception {

    Alert alert = new Alert(Alert.AlertType.CONFIRMATION, "Exit ?", ButtonType.YES, ButtonType.NO);
    alert.show();

    if (alert.getResult() == ButtonType.YES) {
        //this works if put outside of alert
        BlueSlime.scheduler.shutdown();
        super.stop();
    }

    if(alert.getResult() == ButtonType.NO){
        System.out.println("No");
    }

通过将调度程序设为静态,我可以通过从 Main 引用 BlueSLime 来关闭它。这将关闭它,但有更好的方法吗?警报也不起作用,当我关闭程序时,警报框会显示半秒钟,然后消失并让线程再次运行。

【问题讨论】:

  • stop 方法中创建新的GUI 元素为时已晚,因为它在JavaFX 平台关闭时被调用(虽然它是关闭执行程序的正确位置)。它应该只用于清理资源。顺便说一句:有比使用静态执行器更好的方法:将执行器传递给以非静态方式使用它的类。至于让关闭更优雅的方法:可以将ThreadFactory 传递给创建执行程序的方法。您使用返回守护线程的ThreadFactory 会阻止服务保持应用运行。
  • 我明白了,但是将执行程序传递给以非静态方式使用它的类是什么意思?我在我的 GameLogic 类中生成了一个 BlueSlime,它被更新/绘制/清除。我是否必须改为引用 GameLogic 类?

标签: java multithreading javafx alert scheduledexecutorservice


【解决方案1】:

不要使用关闭挂钩。那是蛮力的方法。而是让你的线程守护线程。只需将以下代码添加到您的类中

private static class DaemonThreadFactory implements ThreadFactory {
    public Thread newThread(Runnable r) {
        Thread thread = new Thread(r);
        thread.setDaemon(true);
        return thread;
    }
}

然后将上面的第一行代码更改为

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1, new DaemonThreadFactory());

就是这样。

【讨论】:

  • 哦,哇,感谢您为我简化了它!我在研究时在这里看到了这个例子,但它看起来有点复杂......但是,我在 Main 类的 stop() 方法中的做法是否也被认为是蛮力?
  • 您不必再对守护线程执行此操作了。
【解决方案2】:

像这样添加关闭钩子:

Runtime.getRuntime().addShutdownHook(new Thread(scheduler::shutdown))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-26
    • 2015-07-28
    • 2015-02-08
    • 1970-01-01
    • 2014-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多