Javaで「3秒後に処理を実行したい」「1秒ごとに処理を繰り返したい」といったタイマー処理は、java.util.TimerとTimerTaskを組み合わせれば数行で書けます。
メソッドの使い分けは、1回だけ遅延実行するならschedule(task, delay)、予定時刻どおりに繰り返すならscheduleAtFixedRate、遅れを取り戻さず一定間隔を保つならschedule(task, delay, period)です。
結論を先に言うと、新規実装ではScheduledExecutorServiceが推奨で、Timerが必要になるのは主にレガシーコードの保守や、既存コードの読解の場面です。
この記事では、そのまま動かせるTimerのサンプルコード(OpenJDK 23で動作確認済み)から、TimerTaskの例外でTimerごと止まる落とし穴、ScheduledExecutorServiceへの移行手順まで順に解説します。
PARTS LIST /目次
JavaのTimer(タイマー)とは?

JavaにおけるTimerとは、指定した時間や間隔で特定のタスクを実行するためのクラスです。java.utilパッケージに含まれており、Javaの標準ライブラリの一部として提供されています。
例えば、以下のような処理を実現するのに役立ちます。
ポイント
- アプリケーション起動の5秒後に初期化処理を行う(Spring Boot 3.2以降なら、
@EnableSchedulingを有効にして@Scheduled(initialDelay = 5000)と書けば1回だけ実行する形で代替可) - 毎日深夜0時にログファイルを整理する
- 1分ごとにサーバーの死活監視を行う
バックグラウンドで定期的な処理や遅延実行を行いたい場合に便利な仕組みです。
Timerクラスの基本概要
Timerクラスは、タスクをスケジュールするためのタイマー本体(指揮者)です。
「何秒後に」「何分ごとに」といった指示を登録すると、指定のタイミングで処理を呼び出してくれます。
重要な特徴として、Timerは内部的に単一のバックグラウンドスレッドでタスクを管理します。
つまり、登録されたタスクがいくつあっても、それらは一つのスレッド上で順番に実行されるのです。
このシングルスレッドという性質は、Timerを扱う上で重要なポイントになるので覚えておきましょう。
TimerとTimerTaskの関係
Timerを理解する上で欠かせないのがTimerTaskクラスです。この2つはセットで使われます。
Timer: いつタスクを実行するかを決めるスケジューラー本体TimerTask: 実際に実行される処理内容を書く「タスク本体」(run()メソッドに処理を書く)
まずTimerTaskのrunメソッドの中に実行したい処理を書きます。
そのTimerTaskのインスタンスをTimerのscheduleメソッドなどに渡すことで、タスクのスケジュールが予約されます。
Timer・TimerTaskの使い方

Timerの主な使い方は、単発でタスクを実行する方法と、定期的にタスクを実行する方法の2つに大別されます。
それぞれの代表的なメソッドを見ていきましょう。
単発タスクを実行する(schedule)
一度だけタスクを実行したい場合はschedule(TimerTask task, long delay)メソッドを使います。
このメソッドは、指定したdelay(ミリ秒)が経過した後に、引数で渡されたtaskを一度だけ実行します。
例えば、「10秒後にこの処理を実行する」といった場合に利用できます。
また、schedule(TimerTask task, Date time)という形式もあり、こちらは特定の日時を指定してタスクを予約できます。
「明日の朝8時に実行する」といった制御が可能です。
定期的にタスクを実行する(scheduleAtFixedRate)
タスクを一定間隔で繰り返し実行したい場合にはscheduleAtFixedRate(TimerTask task, long delay, long period)メソッドが便利です。
delay: 最初のタスクが実行されるまでの待機時間(ミリ秒)period: 2回目以降のタスクを実行する間隔(ミリ秒)
このメソッドの大きな特徴は、タスクの開始時間を基準に次の実行スケジュールを決定する点です。
例えば、「10秒ごとに実行」と設定した場合、前のタスクの処理に3秒かかったとしても、次のタスクは7秒後に開始されます。
タスクの実行時間がperiodを超えた場合は、前のタスクが終わり次第、遅延していたタスクがすぐに実行されます。
正確な周期で処理を実行したい場合に適しています。
schedule():前回の実際の実行時刻を基準に繰り返し実行
もう一つ、定期実行のメソッドとしてschedule(TimerTask task, long delay, long period)があります。
scheduleAtFixedRateとよく似ていますが、こちらは前回の実際の実行時刻を基準に次の実行スケジュールを決定する点が異なります(固定遅延)。
例えば、「10秒間隔」で設定した場合、ある回がGCなどで2秒遅れて始まったら、次の実行はその実際の開始時刻から10秒後になります。
つまり、遅れが出るたびに以降の予定が後ろへずれていき、scheduleAtFixedRateのように遅れを取り戻すための連続実行はしません。
処理が遅延しても、遅れを取り戻すための連続実行を避けて一定間隔を保ちたい、というシナリオで有効な方法です。
scheduleとscheduleAtFixedRateの使い分け早見表
3つのメソッドの違いを表で整理すると、目的に応じて素早く選択できます。
負荷集中を避けたいならschedule系(遅れを取り戻さない)、定刻処理を厳密に守りたいならscheduleAtFixedRateを選ぶのが基本方針です。
Timerを使ったコード例
具体的なコードでjava timerの使い方を見ていきましょう。3つのパターン(単発・繰り返し・遅延)を順に紹介します。
簡単なサンプルコード
まずは最もシンプルな例です。
プログラム起動から3秒後(3,000ミリ秒後)に「Hello, Timer!」を表示し、Timerをcancel()して終了します。
import java.util.Timer;
import java.util.TimerTask;
public class SimpleTimerExample {
public static void main(String[] args) {
Timer timer = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
System.out.println("Hello, Timer!");
timer.cancel(); // Timerを終了させないとプログラムが終わりません
}
};
System.out.println("3秒後にタスクを実行します。");
timer.schedule(task, 3000);
}
}
繰り返し処理の例
次に、繰り返し処理の例です。プログラム開始2秒後に最初のタスクを実行し、その後は1秒ごとに現在時刻を表示し続けます。
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class RepeatTimerExample {
public static void main(String[] args) {
Timer timer = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
System.out.println("現在の時刻: " + new Date());
}
};
System.out.println("2秒後から1秒ごとにタスクを繰り返し実行します。");
// 2,000ミリ秒後に開始し、その後1,000ミリ秒ごとに繰り返す
timer.scheduleAtFixedRate(task, 2000, 1000);
}
}
このコードを実行すると、プログラムは終了せずに時刻を表示し続けます。手動で停止させる必要があります。
遅延実行の例
遅延実行は、最初のサンプルコードと同じscheduleメソッドで実現できます。
ここでは、少し応用して特定のDateオブジェクト(日時)を指定してみましょう。
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class DelayTimerExample {
public static void main(String[] args) {
Timer timer = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
System.out.println("指定時刻になりました!");
timer.cancel();
}
};
// 現在時刻から5秒後のDateオブジェクトを生成
long delay = 5 * 1000;
Date executionTime = new Date(System.currentTimeMillis() + delay);
System.out.println(executionTime + " にタスクを実行します。");
timer.schedule(task, executionTime);
}
}
Timerを使う際の5つの注意点
Timerは手軽で便利ですが、実務で使うには知っておくべき重要な注意点が5つあります。
これらを知らないと、予期せぬバグやシステム障害につながる可能性があります。
なおJava 5以降はScheduledExecutorServiceが後継として推奨されており、2026年現在の新規実装では基本的にそちらを使うのがベストプラクティスです。
この記事の注意点は、レガシーコードを保守する際の罠を理解するためにも役立ちます。
マルチスレッド環境での注意
Timerは、内部で単一のスレッドしか持っていません。複数のタスクをスケジュールした場合でも、それらはすべて同じスレッドで順番に実行されます。
もし、あるタスクの処理に長い時間がかかってしまうと、その間、後続のタスクはすべて待たされることになります。
これにより、期待した時刻に処理が実行されないという問題が発生します。
例外発生時の挙動
例外が発生したときの挙動は、Timerクラスの中で最も注意すべきポイントです。
TimerTaskのrunメソッド内で、キャッチされない例外(RuntimeExceptionなど)が発生すると、そのTimerを管理しているスレッドが完全に停止してしまいます。
スレッドが停止すると、そのTimerにスケジュールされていた他のタスクは、エラーになったタスク以降一切実行されなくなります。
エラーハンドリングを怠ると、システムが静かに機能停止に陥る危険があるのです。
私の失敗談:本番で「動いているはずなのに動いていない」状態に陥った話
新人だった頃に、定期バッチの監視ジョブをTimerで実装したことがあります。
テスト環境では問題なく動いていたのに、本番リリース後に「ジョブが朝のうちは動いていたが、午後から記録が途絶えている」とアラートが上がりました。
調査するとログには何も残っておらず、JVMプロセスは生きている。なのに次のタスクが永遠に来ない。半日かけてようやく原因にたどり着きました。
正午の処理でNullPointerExceptionが出て、Timerのスレッドが死んでいたのです。
このとき強烈に学んだのが、TimerTask#run()の中身は必ずtry-catch (Throwable t)で囲み、最低でもログ出力すること。
ScheduledExecutorServiceでも基本は同じですが、Futureから例外を取得できる分こちらの方が安全です。
それ以来、新規実装でTimerを選ぶことはなくなりました。
Timerのキャンセルと終了処理
Timerは、バックグラウンドでスレッドを動かし続けます。
そのため、アプリケーションのメイン処理が終わっても、Timerが動いている限りJavaのプロセスは終了しません。
不要になったTimerは、必ずtimer.cancel()メソッドを呼び出して明示的に終了させる必要があります。
cancel()を呼ばないと、リソースリークの原因となり、サーバーアプリケーションなどでは深刻な問題につながります。
手元検証:cancel()を呼ばずにTimerを生成し続けるとどうなるか
JDK 21(Amazon Corretto 21.0.5)とJDK 23(OpenJDK 23.0.1)で、1秒ごとにnew Timer()を作って定期タスク(schedule(task, 100, 500))を登録し、cancel()を呼ばない、という雑な実装を用意しました(macOSで確認)。
Thread.getAllStackTraces()で、名前が「Timer-」で始まるスレッドの数を数えました(5秒ごとにSystem.gc()も呼んでいます)。
Timerの内部実装(単一バックグラウンドスレッドでObject.wait()に依存する構造)はJDK 21・23のどちらも同じで、結果も同じでした。
- 1秒ごとに新しい
Timerを生成 → Timerのスレッド数が単調に増加(10秒後に10本、1分後に60本) - 同じ実装で
timer.cancel()を毎回呼ぶ → Timerのスレッドは残らない(0本) - 単発のタスク(
schedule(task, 100))なら、cancel()を呼ばなくても実行を終えたTimerはGCで回収され、6本前後で頭打ちになる
定期タスクを登録したTimerでcancel()が呼ばれないコードパスがあると、長時間稼働するサーバではスレッドリークの原因になります。
finallyブロックでcancel()を呼ぶか、try-with-resourcesで囲めるScheduledExecutorServiceを選ぶのが安全です。
scheduleAtFixedRateはどんな挙動をしますか?
scheduleAtFixedRateは、タスクの開始時刻を基準にスケジュールを組みます。もしタスクの実行時間が設定した周期(period)よりも長くなった場合、タスクの実行がどんどん遅延していきます。
そして、遅延したタスクは前のタスクが終わり次第、間隔を空けずに連続で実行されることがあります。
意図しない負荷集中を引き起こす可能性があるため、タスクの処理時間には注意が必要です。
ガベージコレクション(GC)はTimerの実行タイミングに影響しますか?
あまり知られていませんが、Timerの内部実装はObject.wait()メソッドに依存しています。Oracle公式のTimerクラスのドキュメントも「ガベージコレクションなどのバックグラウンド処理によって実行が遅延することがある」と明記しており、GCの一時停止(Stop-The-World)でタイマースレッドの起床が遅れ、タスクの実行タイミングがずれる可能性があります。通常は問題になりませんが、特殊な環境では注意が必要です。
Timerと他の仕組みの比較
ここまでjava timerの注意点を見てきましたが、現在ではより高機能で安全な代替クラスが存在します。
ScheduledExecutorServiceとの違い
ScheduledExecutorServiceとは、スレッドプールを使ってタスクを定期実行できる、java.util.concurrentパッケージのインターフェースです。
Java 5(2004年)から導入され、Timerの欠点を克服した後継APIと位置づけられています。
2026年8月時点の最新LTSはJava 25(2025年9月リリース、8年間サポート)で、定期起動はScheduledExecutorServiceに任せ、実際の処理をJava 21で正式導入された仮想スレッド(Virtual Threads)に渡す構成もあります。
なおJava 17は仮想スレッドを含まないため、その恩恵を受けるにはJava 21以降への移行が前提になります。
いずれにせよ、Timerを新規採用する場面はほぼありません。
ScheduledExecutorServiceは、内部的にスレッドプールを使っているため、複数のタスクを並行して実行できます。
あるタスクが遅延しても、他のタスクに影響を与えません。また、タスク内で例外が発生しても、サービス全体(スレッドプール)が停止することはありません。
ただし、例外を起こした定期タスクそのものは以降実行されなくなる点はTimerと同じで、この点は後述の「手元検証」で詳しく確認します。
具体的に、この記事のscheduleAtFixedRateサンプルをScheduledExecutorServiceに書き換えるとこうなります。
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ScheduledExecutorExample {
public static void main(String[] args) {
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
Runnable task = () -> {
try {
System.out.println("現在の時刻: " + new Date());
} catch (Throwable t) {
t.printStackTrace(); // 例外を握りつぶさず必ずログに出す
}
};
// 2秒後から1秒間隔で繰り返し(TimerのscheduleAtFixedRateと同じ開始時刻基準)
scheduler.scheduleAtFixedRate(task, 2, 1, TimeUnit.SECONDS);
}
}
違いのポイントは3つです。
(1) スレッドプールサイズを引数で指定できる、(2) RunnableまたはCallableを直接渡せる(TimerTask不要)、(3) 例外でスレッドプール全体は停止しない。
Timerからの移行は機械的な置き換えに近く、難しくありません。
手元検証:ScheduledExecutorServiceの定期実行も「例外で止まる」のはTimerと同じ
「例外が発生してもサービス全体が停止しないから堅牢」という説明は正しいのですが、これだけを読むと「例外を起こしたタスク自体は次回以降も律儀に実行され続ける」と誤解しそうになったので、OpenJDK 23.0.1(java -versionで確認)で実際に検証してみました。
300ミリ秒間隔でscheduleAtFixedRateし、2回目の実行でわざとRuntimeExceptionを投げるタスクを、Timer版とScheduledExecutorService版の両方で用意し、2秒間(本来なら6〜7回実行されるはず)待ってから実行回数を数えました。
つまり、「サービス全体が停止しない」のは事実ですが、その定期タスク自体は例外発生後に黙って止まるという点はTimerと変わりません。
違いは、Timerだと同じスレッドに乗っていた他のタスクまで巻き添えで止まる点です。
一方ScheduledExecutorServiceでは影響範囲がそのタスクだけに限定され、Future経由で異常終了を検知できます。
定期実行を止めたくない場合は、タスクの中身をtry-catchで必ず囲む、という結論は変わりません。
scheduleWithFixedDelayとscheduleAtFixedRateの違い
上のコード例ではscheduleAtFixedRateを使いましたが、ScheduledExecutorServiceにはscheduleWithFixedDelayも存在します。
両者の違いは、TimerのscheduleAtFixedRateとschedule(task, delay, period)の関係とほぼ同じです。
scheduleAtFixedRate(command, initialDelay, period, unit): 前回タスクの開始時刻を基準に次回を計算する(TimerのscheduleAtFixedRate相当)scheduleWithFixedDelay(command, initialDelay, delay, unit): 前回タスクの終了時刻を基準に次回を計算する(Timerのscheduleは前回の実際の開始時刻基準なので、基準が異なる点に注意)
正確な周期を厳密に維持したい場合はscheduleAtFixedRate、処理の重なりを避け負荷を平準化したい場合はscheduleWithFixedDelayを選ぶのが基本方針です。
ScheduledExecutorServiceのシャットダウン処理を忘れずに
ScheduledExecutorServiceはTimerと違い、明示的にshutdown()(またはshutdownNow())を呼ばない限りスレッドプールが動き続けます。
Timerのcancel()に相当する終了処理を忘れると、アプリケーション終了時にJVMが正常終了しない、あるいはスレッドリークにつながる点は共通の落とし穴です。
shutdown(): 新規タスクの受付を停止し、実行中のタスクと遅延待ちの単発タスクは完了させてから終了する(定期タスクの以降の実行は既定でキャンセルされる)shutdownNow(): 実行中のタスクを中断し、待機中のタスクも破棄して即座に終了する
アプリケーションのライフサイクルに合わせて、@PreDestroyやシャットダウンフックでshutdown()を呼び出す実装にしておくと安全です。
実務でよく使われるケース
新規でスケジュール処理を実装する場合、ScheduledExecutorServiceを利用するのが一般的です。
Timerは、その多くの欠点から、現在では積極的に利用される場面はほとんどありません。
ただし、古いシステムの保守や既存ライブラリのコードリーディングでjava timerに出会う場面はまだあります。
Timerの仕組みや注意点を理解しておくことは、Javaエンジニアにとって今でも実用的な知識です。
私の判断基準としては、「レガシーのTimer実装を見つけたら即座に置き換えるべきか」は一律には決めていません。
本番で稼働中かつ障害実績がないなら、無理に触らないのが基本方針です。
前述の「手元検証」で示したとおり、例外で止まるのは同じTimerに載っているタスクだけで、他のTimerやJVM全体には波及しません。1つのTimerに1タスクだけの設計であれば、リスクとリファクタリングコストが見合わないことが多いためです。
逆に、複数のタスクを1つのTimerに相乗りさせている実装(=1つの例外が他のタスクまで巻き添えにする構造)を見つけたときは話が別です。
優先度を上げてScheduledExecutorServiceへの置き換えを提案しています。
新規実装と既存コードの保守で、どの仕組みを選ぶかを図にまとめると次のようになります。
@ScheduledTimerからの移行チェックリスト
既存のTimer実装をScheduledExecutorServiceに置き換える際は、以下の4点を順に確認すると移行漏れを防げます。
- TimerTaskをRunnable/Callableに置き換える:
run()メソッドの中身をそのままRunnableのラムダに移す - scheduleとscheduleAtFixedRateの対応を確認する:
scheduleAtFixedRateはscheduleAtFixedRateに、Timer#schedule(task, delay, period)(前回の実際の開始時刻から一定間隔)はscheduleWithFixedDelay(前回の終了時刻から一定間隔)が最も近いが基準が少し異なるので、間隔の意味を確認して選ぶ - cancel()をshutdown()に置き換える: 終了処理を書き忘れるとTimer時代と同じくスレッドリークになる
- 例外処理をtry-catchからFutureベースに見直す:
scheduleAtFixedRate()などが返すScheduledFutureからget()で例外を取得できるようにしておくと、握りつぶしを防げる
Spring @Scheduledやcronとの関係
Spring Bootを使っているプロジェクトでは、java timerを直接書く場面はさらに少なくなります。
Springの@Scheduledアノテーションを使うと、メソッドにアノテーションを付けるだけで定期実行が実装できるためです。
@Scheduled(fixedRate = 1000):scheduleAtFixedRate相当(開始時刻基準)@Scheduled(fixedDelay = 1000): 終了時刻基準(Timerのscheduleとは基準が異なる)@Scheduled(cron = "0 0 0 * * *"): cron式で柔軟なスケジュール
OSレベルのcronやKubernetesのCronJobと比べると、Spring側で実装する利点はアプリ内のDIコンテナや例外通知の仕組みをそのまま使えることです。
常時起動のWebアプリならSpringで、バッチ単発実行ならOS cronで、と役割を分けるのが定石です。
私の失敗談:@Scheduledで起動したバッチが本番でOOMを起こした話
Spring Batchを@Scheduledで定期起動する構成で、chunk sizeを1000に設定して本番投入したところ、想定より対象データが多い日にメモリ不足(OutOfMemoryError)でジョブが落ちたことがあります。
原因調査には2時間ほどかかりましたが、修正自体はchunk sizeを100に下げるだけの5分で完了しました。
この一件で学んだのは、「定期実行の仕組み(Timerか@Scheduledか)をどれだけ堅牢にしても、実行される処理自体のリソース設計が甘ければ意味がない」ということです。
TimerやScheduledExecutorServiceのスレッド管理・例外処理を丁寧に作り込んでも、中身のバッチ処理がメモリを食い潰せば同じことが起きます。
chunk sizeやバッチサイズは、本番データ量を想定してまず小さめに始めるのが安全です。
Java Timerに関するよくある質問
Q. Timerは非推奨ですか?
公式に「非推奨」(@Deprecated)にはされていませんが、Java 5以降はScheduledExecutorServiceが事実上の後継として位置づけられています。新規開発でわざわざTimerを選ぶ理由はほぼありません。
Q. Timerのスレッド数は変更できますか?
Timerはシングルスレッド固定で、スレッド数を増やす設定はありません。並列実行が必要ならExecutors.newScheduledThreadPool(n)でスレッド数を指定できるScheduledExecutorServiceを使ってください。
Q. cancel()を呼ばないとどうなりますか?
内部のバックグラウンドスレッドが動き続け、定期タスクが残っているとJavaプロセスが終了しません(単発タスクだけでTimerへの参照が無くなった場合は、GC後にスレッドが終了することもあり、終了タイミングはGC任せになります)。mainメソッドが返ってもJVMが終了しないように見えるのはこれが原因です。Webアプリやサーバ上でTimerのリークが続くと、リソース枯渇の温床になります。
Q. ミリ秒以下の精度は出ますか?
JVMとOSのスケジューラに依存しますが、ミリ秒精度を保証するものではありません。高精度が必要な場面ではScheduledExecutorService+System.nanoTime()を使うか、リアルタイムJVMの導入を検討してください。
Q. TimerとScheduledExecutorServiceは例外発生時に同じ挙動になりますか?
はい、「例外を起こした定期タスクが以降実行されなくなる」という結果自体は同じです。違うのは影響範囲で、Timerは同じスレッドに乗っていた他のタスクまで巻き添えで止まりますが、ScheduledExecutorServiceはそのタスクだけに影響が限定され、Future経由で例外を検知できます。詳しくはこの記事の「手元検証」で実測結果を紹介しています。
Q. ScheduledExecutorServiceのshutdown()を呼び忘れるとどうなりますか?
Timerのcancel()忘れと同様、スレッドプールが動き続けてJavaプロセスが終了しません。長時間稼働するアプリケーションではスレッドリークの原因になるため、@PreDestroyやシャットダウンフックでshutdown()を呼ぶ実装にしておく必要があります。
Q. Spring BootならTimerより@Scheduledを使うべきですか?
はい、Spring Bootプロジェクトでは@Scheduledを使うのが基本です。DIコンテナや例外通知の仕組みをそのまま使え、fixedRate/fixedDelay/cronで用途に応じた指定もできます。Timerを直接書く必要があるのは、Springを使わない小規模なJavaプログラムやレガシーコードの保守に限られます。
まとめ
今回はJavaのTimerクラスについて、基本的な使い方から実務で役立つ注意点まで詳しく解説しました。
Timerを理解するメリット
Timerは古い技術ですが、その仕組みを学ぶことで、タスクスケジューリングの基本的な考え方や、シングルスレッドモデルの課題を深く理解できます。
なぜScheduledExecutorServiceのような後継技術が必要になったのか、その背景を知る上でもTimerの知識は役立ちます。
次に学ぶべき関連クラス
Timerの学習を終えたら、次はぜひ以下のクラスについて学んでみてください。
ScheduledExecutorService:Timerのモダンな代替技術です。より堅牢で柔軟なスケジュール管理ができます。ExecutorService: Javaの並列処理の基本となるインターフェースで、スレッドプールを簡単に扱うための仕組みです。CompletableFuture: Java 8から導入された、非同期処理をより高度に、そして簡潔に記述するためのクラスです。- Virtual Threads(Java 21で正式導入、2026年時点の最新LTSであるJava 25でも安定運用中): 軽量スレッドで、大量の並行スケジュールを低コストで処理できます。
ScheduledExecutorServiceで起動した処理を仮想スレッドに渡す使い方もできます。 - Spring
@Scheduled: Spring Bootアプリケーションでの定期実行のデファクトスタンダードです。
これらの技術を習得することで、Javaでの並行処理や非同期処理への理解が一層深まるでしょう。
| REV. | DATE | 内容 |
|---|---|---|
| 6 | 2026-10-15 | 図解を描き直し(図面のデザインにそろえた) |
| 5 | 2026-10-14 | 一人称と言い回しの表記をそろえた。雰囲気だけの挿絵を外した |
| 4 | 2026-10-04 | 記載内容の事実確認と修正 |
| 3 | 2026-08-22 | 2026年8月時点の情報で全体を見直し(古い記述を5件更新) |
| … ほか1回の改訂 | ||
| 1 | 2025-08-27 | 初版 |





