如何停止 ScheduledExecutorService?

How to stop a ScheduledExecutorService?

程序在九次打印后结束:

class BeeperControl {

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

    public void beep() {
        final Runnable beeper = new Runnable() {
            public void run() {
                System.out.println("beep");
            }
        };
        final ScheduledFuture<?> beeperHandle = scheduler.scheduleAtFixedRate(
                beeper, 1, 1, SECONDS);
        scheduler.schedule(new Runnable() {
            public void run() {
                beeperHandle.cancel(true);
            }
        }, 1 * 9, SECONDS);
    }

    public static void main(String[] args) {
        BeeperControl bc = new BeeperControl();
        bc.beep();
    }
}

如何停止进程(例如 java eclipse 中的进程),因为它在 9 秒的时间限制后没有停止?

您遇到的问题是,在您取消蜂鸣任务后,调度程序会保持活动线程。

如果存在活动的非守护线程,则 JVM 保持活动状态。

它保留此线程的原因是您已在这一行中告诉它这样做:

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

注意 newScheduledThreadPool(int corePoolSize) 的文档:

corePoolSize - the number of threads to keep in the pool, even if they are idle.

因此,您有两种可能的方法导致 JVM 终止:

  1. 0 传递给 newScheduledThreadPool 而不是 1。调度程序不会保留活动线程,JVM 将终止。

  2. 关闭调度程序。无论如何,您都应该这样做以释放其资源。因此,将匿名 Runnable 中的 run 更改为:

    public void run() {
        beeperHandle.cancel(true);
        scheduler.shutdown();
    }
    

(实际上,您不需要那里的 cancel - shutdown 将在下一个 "beep" 完成后立即生效。)