Java の ExecutorService の使い方について

Java の ExecutorService の使い方について

このページでは、Java の ExecutorService を活用する方法について詳しく解説します。各セクションにジャンプするリンクを用意しました。

ExecutorServiceとは

ExecutorService は、Java でスレッドプールを利用するためのインターフェースです。複数のタスクを効率よく並列処理するために、スレッドプールを使用してリソースを再利用します。

主な特徴:

  • スレッドを手動で管理する手間を軽減
  • スレッドのライフサイクルを自動的に制御
  • 複数のタスクを効率的に処理

ExecutorServiceの作成方法

ExecutorService は Executors クラスを使用して作成します。以下は一般的な作成方法です。

固定スレッドプール


import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class FixedThreadPoolExample {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(3);

        Runnable task = () -> {
            System.out.println("Task executed by " + Thread.currentThread().getName());
        };

        for (int i = 0; i < 5; i++) {
            executor.submit(task);
        }

        executor.shutdown();
    }
}
    

固定スレッドプールは指定した数のスレッドを再利用します。

キャッシュスレッドプール


ExecutorService executor = Executors.newCachedThreadPool();
    

キャッシュスレッドプールは必要に応じてスレッドを生成し、アイドル状態のスレッドを再利用します。

シングルスレッドエグゼキュータ


ExecutorService executor = Executors.newSingleThreadExecutor();
    

シングルスレッドエグゼキュータは、1つのスレッドでタスクを逐次実行します。

submitメソッドとexecuteメソッドの違い

submitexecute はタスクを実行するために使用されますが、動作にいくつかの違いがあります。

execute

Runnable を引数に取り、戻り値はありません。


executor.execute(() -> System.out.println("Task executed!"));
    

submit

Callable または Runnable を引数に取り、戻り値として Future オブジェクトを返します。


Future<String> result = executor.submit(() -> {
    return "Task completed!";
});
System.out.println(result.get()); // "Task completed!"
    

タスクの管理

ExecutorService ではタスクの管理が容易です。

複数のタスクを並列実行


List<Callable<String>> tasks = Arrays.asList(
    () -> "Task 1",
    () -> "Task 2",
    () -> "Task 3"
);

List<Future<String>> results = executor.invokeAll(tasks);

for (Future<String> result : results) {
    System.out.println(result.get());
}
    

最初に完了したタスクの結果を取得


String result = executor.invokeAny(tasks);
System.out.println(result); // 最初に完了したタスクの結果
    

ExecutorServiceのシャットダウン

ExecutorService を使用後は必ずシャットダウンしてください。

シャットダウンの方法


executor.shutdown(); // 新しいタスクの受け付けを停止
if (!executor.awaitTermination(1, TimeUnit.MINUTES)) {
    executor.shutdownNow(); // 強制終了
}
    

応用例

スケジュールタスクの実行


ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

scheduler.schedule(() -> System.out.println("Task executed after delay"), 5, TimeUnit.SECONDS);
scheduler.shutdown();
    

カスタムスレッドプール


ExecutorService customExecutor = new ThreadPoolExecutor(
    2, 4, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>()
);
    

カスタムスレッドプールを使用すると、柔軟な設定が可能です。

以上で ExecutorService の基本的および応用的な使い方の解説は終わりです。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です