ThreadPoolExecutorクラスには4つのコンストラクタがあり、最終的に以下のように呼び出されます:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
コンストラクターには、以下のように合計7つのパラメーターがあります:
corePoolSize
タスクが送信されると、スレッド・プールは、現在のスレッド数が corePoolSize に等しくなるまで、タスクを実行する新しいスレッドを作成します。現在のスレッド数が corePoolSize の場合、タスクはブロッキング・キューに保存され、実行されるのを待ちます。restartAllCoreThreads() メソッドを呼び出すと、スレッド・プールは事前にすべてのコア・スレッドを作成して起動します。スレッド数が corePoolSize 以下の場合、デフォルトでは、スレッドは常にスレッドプールに住み、スレッドはすぐにアイドル状態になります。allowCoreThreadTimeOut を true に設定すると、スレッド数に関係なく、一定時間以上アイドル状態が続くとスレッドは破棄されます。
maximumPoolSize
スレッド・プールで許可されるスレッドの最大数。現在のブロッキング・キューが満杯で、タスクが投入され続けている場合、現在のスレッド数が maximumPoolSize よりも少ないことを条件に、タスクを実行するために新しいスレッドが作成されます;
keepAliveTime
スレッドがアイドル状態のときの生存時間、つまり、スレッドが実行するタスクがないときに、その時間を存続させ続けます。デフォルトでは、このパラメータはスレッド数がcorePoolSizeより大きい場合にのみ有効です。allowCoreThreadTimeOutをtrueに設定すると、スレッド数に関係なく、スレッドが一定時間以上アイドル状態のときにスレッドが破棄されます。
unit
keepAliveTimeの単位。timeUnitは以下のような列挙型です:
- NANOSECONDS 1マイクロ・ミリ秒= 1マイクロ秒 / 0010
- MICROSECONDS 1マイクロ秒= 1ミリ秒 / 0010
- MILLISECONDS 1ミリ秒= 1秒数 /0010
- SECONDS
- MINUTES
- HOURS
- DAYS
workQueue
実行待ちのタスクを保持するためのブロッキング・キューで、タスクは Runable インターフェースを実装する必要があります:
- ArrayBlockingQueue: 配列構造に基づく境界付きブロッキングキュー;
- LinkedBlockingQuene: リンクテーブル構造に基づく非束縛ブロッキングキューで、タスクを FIFO でソートします;
- SynchronousQuene: ブロッキングキューは要素を保存しません。各挿入操作は、他のスレッドが削除操作を呼び出すまで待機する必要があります;
threadFactory
スレッドを作成するためのファクトリーで、カスタムスレッドファクトリーを使用すると、たとえば新しく作成されたスレッドごとに認識可能なスレッド名を設定できます:
public class OneMoreThreadFactory implements ThreadFactory {
private static final AtomicInteger poolNumber = new AtomicInteger(1);
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
public OneMoreThreadFactory() {
namePrefix = "OneMoreThread-" + poolNumber.getAndIncrement() + "-";
}
@Override
public Thread newThread(Runnable r) {
return new Thread( r, namePrefix + threadNumber.getAndIncrement());
}
}
handler
スレッドプール飽和戦略、ブロッキングキューがいっぱいになり、無料のワーカースレッドがない場合、タスクを提出し続ける場合は、タスクに対処するための戦略を採用する必要があり、スレッドプールは、4つの戦略を提供しています:
- AbortPolicy: 例外が直接スローされます;
- CallerRunsPolicy:呼び出し元のスレッドでタスクを実行します;
- DiscardOldestPolicy: ブロッキング・キューの先頭にあるタスクを破棄し、現在のタスクを実行します;
- DiscardPolicy: タスクを直接破棄します;