スレッドプールの基本概念
スレッドプールとは、スレッドの作成・破棄のオーバーヘッドを削減し、リソースを効率的に管理するための仕組みです。事前に一定数のスレッドを生成し、タスク到着時に再利用することで、システムのパフォーマンス向上を図ります。
主要なクラスとインターフェース
ExecutorServiceインターフェース: スレッドプール操作の基本機能を定義Executorsユーティリティクラス: 各種スレッドプールのファクトリメソッドを提供ThreadPoolExecutorクラス: スレッドプールの核となる実装クラス
主要メソッド
// 戻り値なしのタスク実行
void execute(Runnable task);
// 戻り値ありのタスク実行
Future<ResultType> submit(Callable<ResultType> task);
// 穏やかなシャットダウン
void shutdown();
// 即時シャットダウン
List<Runnable> shutdownNow();
// 終了待機
boolean awaitTermination(long duration, TimeUnit unit);
スレッドプールの動作フロー
- 新規タスク到着時、アイドル状態のワーカースレッドが存在すれば割り当て
- アイドルスレッドなしの場合、コアスレッド上限未達であれば新規コアスレッド作成
- コアスレッド上限到達時、タスクキューの空き状況を確認
- キューに空きがあればタスクを追加、後続のアイドルスレッドが順次処理
- キュー満杯時、最大スレッド数上限未達であれば非コアスレッドを追加作成
- 最大スレッド数も到達した場合、拒否ポリシーを適用
構成パラメータの詳細
| パラメータ | 説明 |
|---|---|
corePoolSize | 常駐する最小スレッド数。作成後は基本的に回収されない |
maximumPoolSize | 許可される最大スレッド数(コアスレッド含む) |
keepAliveTime | 非コアスレッドのアイドル状態許容時間 |
unit | 上記時間の単位(TimeUnit列挙型) |
workQueue | 待機タスクを保持するBlockingQueue実装 |
threadFactory | スレッド生成をカスタマイズするファクトリ |
handler | タスク拒否時の処理戦略(RejectedExecutionHandler) |
標準スレッドプールの実装例
固定サイズスレッドプール
ExecutorService fixedPool = Executors.newFixedThreadPool(5);
// 実装詳細:
// - コア数と最大数が同一値
// 無制容量のLinkedBlockingQueue使用
ThreadPoolExecutor fixedImpl = new ThreadPoolExecutor(
5, 5, 0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>()
);
キャッシュ型スレッドプール
ExecutorService cachedPool = Executors.newCachedThreadPool();
// 特徴:
// - コアスレッド数: 0
// - 最大スレッド数: Integer.MAX_VALUE
// - アイドルタイムアウト: 60秒
// - SynchronousQueueによる直接ハンドオフ
単一スレッドプール
ExecutorService singlePool = Executors.newSingleThreadExecutor();
// 構成:
// - コア/最大スレッド数: 1
// - 終了保証付きラッパーでカプセル化
スケジュール対応スレッドプール
ScheduledExecutorService scheduledPool =
Executors.newScheduledThreadPool(3);
// 機能:
// - 指定コア数で初期化
// - DelayedWorkQueueによる遅延・定期実行サポート
// - schedule(), scheduleAtFixedRate()等の特殊メソッド提供