Concurrency 中級

Timerタスクからスケジュール済みエグゼキュータへ

堅牢なスケジュール処理のためにTimerとTimerTaskをScheduledExecutorServiceに置き換える。

✕ Timer and TimerTask
Timer timer = new Timer("refresh-timer");
timer.scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        refresh();
    }
}, 0, 60_000);
✓ ScheduledExecutorService
ScheduledExecutorService scheduler =
        Executors.newScheduledThreadPool(2);

scheduler.scheduleAtFixedRate(
        this::refresh, 0, 1, TimeUnit.MINUTES);
このコードに問題がありますか? お知らせください。
🧵

優れた分離性

設定可能なスレッドプールにより、無関係なスケジュールが1つの脆弱なワーカーを共有することを防ぐ。

🛡

堅牢な実行

1つのタスクの失敗がスケジューラ自体を終了させることはない。

🎛

制御可能なライフサイクル

Future、キャンセル、遅延、シャットダウンは標準のエグゼキュータAPIを使用する。

旧来のアプローチ
TimerとTimerTask
モダンなアプローチ
ScheduledExecutorService
JDKバージョン
5
難易度
中級
Timerタスクからスケジュール済みエグゼキュータへ
利用可能

JDK 5(2004年9月)以降広く利用可能

Timerはすべてのタスクを1つのスレッドで実行するため、実行時間の長いタスクが他のタスクを遅延させ、未処理の例外がタイマースレッドを終了させてしまう。ScheduledExecutorServiceはエグゼキュータフレームワークを使用し、複数のワーカーをサポートし、ScheduledFutureハンドルを返し、明示的なライフサイクル管理を提供する。所有するコンポーネントは、不要になったらスケジューラをシャットダウンする必要がある。