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
難易度
中級
JDKサポート
Timerタスクからスケジュール済みエグゼキュータへ
利用可能
JDK 5(2004年9月)以降広く利用可能
仕組み
Timerはすべてのタスクを1つのスレッドで実行するため、実行時間の長いタスクが他のタスクを遅延させ、未処理の例外がタイマースレッドを終了させてしまう。ScheduledExecutorServiceはエグゼキュータフレームワークを使用し、複数のワーカーをサポートし、ScheduledFutureハンドルを返し、明示的なライフサイクル管理を提供する。所有するコンポーネントは、不要になったらスケジューラをシャットダウンする必要がある。
関連ドキュメント
証明