web-dev-qa-db-ja.com

ScheduledExecutorServiceを停止するには?

プログラムは9枚の印刷後に終了します。

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プロセスなど)は、9秒の制限時間後に停止しないため?

14
ferro

あなたが持っている問題は、ビープ音タスクをキャンセルした後、スケジューラがライブスレッドを保持することです。

デーモン以外のライブスレッドがある場合、JVMは存続します。

このスレッドを維持する理由は、次の行でそうするように指示したためです。

_private final ScheduledExecutorService scheduler
        = Executors.newScheduledThreadPool(1);
_

newScheduledThreadPool(int corePoolSize)のドキュメントに注意してください:

corePoolSize-アイドル状態であっても、プールに保持するスレッドの数。

したがって、JVMを終了させる方法は2つあります。

  1. _0_を1ではなくnewScheduledThreadPoolに渡します。スケジューラはライブスレッドを保持せず、JVMが終了します。

  2. スケジューラーをシャットダウンします。とにかく、そのリソースを解放するためにそうすることになっています。匿名のrunRunnableを次のように変更します。

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

(実際、cancelは必要ありません。shutdownは次の「ビープ音」が完了するとすぐに有効になります。)

20
RealSkeptic