Java ExecutorService クラス
ExecutorService は Java 並行プログラミングにおける中核インターフェースであり、それはjava.util.concurrentパッケージに属します。
ExecutorService は、より高度なスレッド管理方式を提供し、開発者が手動でスレッドを作成・管理することなく、非同期タスクを効率的に実行できるようにします。
ExecutorService の主な役割は次のとおりです:
- スレッドプール管理:スレッドのライフサイクルを自動管理し、スレッドの作成と破棄のオーバーヘッドを削減します。
- タスクスケジューリング:タスクの送信をサポートし、
Runnable或Callableタスクの実行状態を追跡するためのFutureオブジェクトを返します。 - リソース最適化:スレッドプールでスレッドを再利用し、システムパフォーマンスを向上させます。
ExecutorService のコアメソッド
ExecutorService は、タスクの実行を送信・管理・制御するためのさまざまなメソッドを提供します。以下は主要なメソッドです:
submit()
1つのタスク(Runnable 或 Callable)を送信し、Futureオブジェクトを返します。これにより、タスクの完了を確認したり戻り値を取得したりできます。
例
Future<?> future = executor.submit(() -> {
System.out.println("Task is running");
});
execute()
タスクの送信のみに使用され、Runnable結果は返しません。
例
System.out.println("Task executed");
});
shutdown()
スレッドプールをグレースフルにシャットダウンし、新しいタスクは受け付けませんが、送信済みのタスクが完了するまで待機します。
例
shutdownNow()
スレッドプールを直ちにシャットダウンし、実行中のすべてのタスクの中断を試み、未実行のタスクのリストを返します。
例
awaitTermination()
すべてのタスクが完了するかタイムアウトするまで、スレッドプールのシャットダウンを待機します。
例
ExecutorService の作成方法
Java は、さまざまなタイプのスレッドプールを作成するためのExecutorsユーティリティクラスを提供しています:
newFixedThreadPool(int nThreads)
固定サイズのスレッドプールを作成します。負荷が安定しているタスクに適しています。
例
newCachedThreadPool()
キャッシュ型スレッドプールを作成します。短命の非同期タスクに適しています。
例
newSingleThreadExecutor()
単一スレッドのスレッドプールを作成します。順次実行されるタスクに適しています。
例
newScheduledThreadPool(int corePoolSize)
定時実行または周期的なタスクをサポートするスレッドプールを作成します。
例
使用例
Runnable タスクを送信する
例
executor.submit(() -> {
System.out.println("Task 1 running");
});
executor.submit(() -> {
System.out.println("Task 2 running");
});
executor.shutdown();
Callable タスクを送信して結果を取得する
例
Future<String> future = executor.submit(() -> {
Thread.sleep(1000);
return "Task completed";
});
try {
String result = future.get(); // タスクが完了するまでブロックする
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
}
executor.shutdown();
ベストプラクティス
スレッドプールのサイズを適切に設定する:
- CPU 集約型タスク:
线程数 = CPU 核心数 + 1 - I/O 集約型タスク:
线程数 = CPU 核心数 * 2
- CPU 集約型タスク:
メモリリークを避ける:
- 必ず呼び出して、
shutdown()或shutdownNow()スレッドプールをシャットダウンしてください。
- 必ず呼び出して、
例外処理:
- を使用して
try-catchタスク内の例外をキャッチし、スレッドが予期せず終了するのを防ぎます。
- を使用して
を使用して
Futureタスクを管理します。:- を通じて
Future.get()タスクの結果を取得したり、タスクの状態を確認したりします。
- を通じて