首页 > 解决方案 > 计划进程完成后如何正确终止我的java程序?

问题描述

我有一个简单的 java 程序,用于生成元素并在特定时间每 X 秒将它们插入 DB。

生成是用scheduleAtFixedRate. 只有其中之一。

我希望我的程序在计划任务结束后完全退出。为此,我System.exit()在取消任务时使用,但这是正确的方法吗?

这是我当前的代码:

public static void main(String[] args) throws InterruptedException {

        c = generateDbConnection(url, user, password);

        if (c != null) {
            s = generateDbStatement(c);
        } else {
            System.out.println("ERROR");
            return;
        }
        initialTimestamp = new Date();
        TimeUnit.SECONDS.sleep(1);
        generateForAnHour();

    }

    private final static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

    /**
     * Generator thread handler Uses Statement from main function
     */
    public static void generateForAnHour() {
        final Runnable runner = new Runnable() {
            public void run() {
                String[][] data = new String[numberOfIds][2];
                for (int i = 0; i < numberOfIds; i++) {
                    data[i] = generateDevice();
                    insertDevice(s, data[i][0], data[i][1]);
                }
                quantityOfIds += numberOfIds;
            }
        };

        final ScheduledFuture<?> generatorHandle = scheduler.scheduleAtFixedRate(runner, 0, 5, TimeUnit.SECONDS);
        scheduler.schedule(new Runnable() {
            public void run() {
                generatorHandle.cancel(true);
                System.out.println("Scheduled ID generator terminated.");
                System.exit(0); //TODO Is it really correct way to do it
            }
        }, timeToRun, TimeUnit.SECONDS);
    }

标签: javaexecutorservice

解决方案


如果程序具有更多功能,我不确定这是否是停止执行程序的正确方法,但我个人认为这是一种不错的方法。:D

因此,事实证明,ScheduledExecutorService似乎使用默认创建了非守护线程ThreadFactory,也许我们需要为其提供一个守护线程。

但是,如果我们调用ExecutorService#shutdown或 forceful ExecutorService#shutdownNow,它将停止两个任务的执行,从而删除阻止应用程序结束其工作的线程:

private final static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

public static void main(String[] args) {
    // Some service code here
    generateForAnHour();
}

public static void generateForAnHour() {
    // Some code that does work
    final Runnable runner = () -> System.out.println("Running...");

    final ScheduledFuture<?> generatorHandle = scheduler.scheduleAtFixedRate(runner, 0, 1, TimeUnit.SECONDS);
    // Code that interrupts the worker after a specified time
    scheduler.schedule(scheduler::shutdown, 5, TimeUnit.SECONDS);
}

输出:

Running...
Running...
Running...
Running...
Running...
Running...

Process finished with exit code 0

我希望这将有所帮助。:D


推荐阅读