ScheduledThreadPoolとSingleThreadExecutorの違いとは?比較表とコード例で徹底解説
Javaの並行処理において、ScheduledThreadPool(スケジュール済みスレッドプール)とSingleThreadExecutor(シングルスレッドエグゼキュータ)は、どちらもExecutorsファクトリクラスから生成できる代表的なスレッドプールです。名前は似ていますが、その設計思想や内部動作、適したユースケースは大きく異なります。本記事では、両者の違いを比較表と実際のコード例を交えてわかりやすく解説します。
ScheduledThreadPoolとSingleThreadExecutorの違い一覧
| No. | 項目 | ScheduledThreadPool | SingleThreadExecutor |
|---|---|---|---|
| 1 | 基本動作 | 指定した遅延時間の経過後にタスクを実行したり、一定間隔で定期的に繰り返し実行したりできるスレッドプールを生成します。 | タスクは必ず投入された順番に実行され、同時にアクティブになるタスクは常に1つだけであることが保証されます。 |
| 2 | キュー | DelayQueue(遅延キュー)を使用し、時間的な遅延に基づいてタスクをスケジューリングします。 | ブロッキングキュー(BlockingQueue)を使用してタスクを管理します。 |
| 3 | スレッドの生存期間 | アイドル状態であっても、生成時に指定した数のコアスレッドがプール内に維持され続けます。 | タスクの実行中にスレッドが異常終了した場合でも、新しいスレッドが自動的に再生成され、処理が継続されます。 |
| 4 | スレッドプールサイズ | 生成時に指定した固定サイズのスレッドプールを持ちます。 | 常に1つのスレッドのみで動作します。 |
| 5 | 主なユースケース | 同時に実行するタスク数を制限したい場合や、遅延実行・定期実行が必要なバッチ処理に適しています。 | Task1がTask2より必ず先に実行されるようにしたいなど、タスクの実行順序を厳密に保証したい場合に適しています。 |
ScheduledThreadPoolの使用例
以下の例では、10個のスレッドを持つスケジュール済みスレッドプールを作成し、10秒後の一回限りの実行と、15秒後に開始して以降10秒間隔での定期実行を登録しています。
public class ScheduledThreadPoolExample {
public static void main(String args[]) {
ScheduledExecutorService services = Executors.newScheduledThreadPool(10);
// 10秒後に一度だけタスクを実行
services.schedule(new Task(), 10, TimeUnit.SECONDS);
// 15秒後に初回実行し、以降は10秒間隔で繰り返し実行
services.scheduleAtFixedRate(new Task(), 15, 10, TimeUnit.SECONDS);
}
}
public class Task implements Runnable {
@Override
public void run() {
System.out.println("In Run");
}
}
SingleThreadExecutorの使用例
以下の例では、単一スレッドのエグゼキュータを作成し、タスクを送信(submit)しています。複数のタスクを投入しても、それらは必ず1つずつ順番に処理されます。
public class Main {
public static void main(String args[]) {
ExecutorService services = Executors.newSingleThreadExecutor();
Future<?> future = services.submit(new Task());
}
}
public class Task implements Runnable {
@Override
public void run() {
System.out.println("In Run");
}
}
まとめ:使い分けのポイント
ScheduledThreadPoolは、タイマー処理や定期バッチのように「いつ実行するか」を制御したい場面に最適です。一方、SingleThreadExecutorは、ログ出力やイベント処理のように、複数のタスクを決められた順序で確実に1つずつ処理したい場面で威力を発揮します。アプリケーションの要件に応じて適切なエグゼキュータを選択することで、安全かつ効率的な並行処理を実現できます。
-
JavaにおけるThreadとRunnableの違いを徹底解説!使い分けのポイント
Javaで新しいスレッドを作成する方法は主に2つあります。1つ目はThreadクラスを継承(extends)する方法、2つ目はRunnableインターフェースを実装(implements)する方法です。それぞれの特徴と違いを理解することで、状況に応じた適切な選択ができるようになります。 スレッド作成の2つの方法 1. Threadクラスを継承する方法 Threadクラスのサブクラスとして新しいクラスを宣言し、そのサブクラス内でrun()メソッドをオーバーライドします。その後、サブクラスのインスタンスを生成し、start()メソッドを呼び出すことでスレッドが実行されます。 2. Runna
-
Javaにおける例外(Exception)とエラー(Error)の違いを徹底解説
Javaにおいて、例外(Exception)とエラー(Error)はどちらも Throwable クラスのサブクラスです。しかし、両者には明確な違いがあり、堅牢なアプリケーションを開発するうえで、それぞれの特性を正しく理解することは非常に重要です。 エラー(Error)とは エラーは、主にシステムリソースの不足によって発生する深刻な問題を示します。この種の問題はアプリケーション側でキャッチ(捕捉)すべきものではなく、基本的にプログラマーが対処できる範囲を超えています。代表的な例としては、システムクラッシュやメモリ不足(OutOfMemoryError)などが挙げられます。 エラーはほとんどの