Javaのスレッドプールのパラメータおよび方法
1.スレッドプールの状態
INT ThreadPoolExecutorは、スレッドプールの状態の3ビットを表すために使用される、低番号は、スレッド29を示し
州名 | 高3 | 新しいタスクを受け取ります | キュー処理タスクをブロック | 説明 |
---|---|---|---|---|
ランニング | 111 | と | と | |
シャットダウン | 000 | N | と | あなたは、新しいタスクを受信しませんが、キューをブロックし、残りのタスクを扱います |
やめる | 001 | N | N | タスクが実行されている割り込みとキューのタスクをブロック破棄 |
片付け | 010 | 全タスクが終了すると、アクティブなスレッドが最後に入ろうとしている0 | ||
TERMINATED | 011 | 終了状態 |
2.スレッドプールのパラメータ
ThreadPoolExecutor executor = new ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
Javaスレッドプール上で最も完全なパラメータ、三つの追加少なくとも1つまたはこの構成プロセスにおける2つのコンストラクタのパラメータである4つの施工方法。
2.1 int型corePoolSize
これは、(コアスレッドが回収されず、依然として存在し、スレッドがアイドル状態のとき)スレッドの最も数のために予約されているプール内のスレッドのコアの数を表します
2.2 int型maximumPoolSize
これは、一時的に新しいスレッドを作成し、まだ作業キュータスクがある場合、スレッドのコア数は、占有されているとき、あるスレッドの最大数を表します。タスクを解決すると、スレッドが破棄されます。(一時的な労働者に相当)
2.3長期keepAliveTimeが
指定された時間は、破壊された後、スレッドは、アイドル状態での生存時間の代表。ときのための緊急スレッド(一時的な)
2.4 TimeUnitでユニット
測定単位の代理のKeepAliveTime
2.5 BlockingQueueのワークキュー
作業キューの代表であるキューをブロックします。新しいタスクがアイドル状態のスレッドを待っているそれらのタスクキューに追加されたタスクを取得しています。
一般に、キューの4つのJDKがあります。
2.5.1 ArrayBlockingQueue
アレイベースの有界ブロッキングキューには、キューをブロックのサイズを指定します。たびタスク、タスクキューがいっぱいになったとき、スクラッチ取得タスクからキューの最後、およびスレッド原因たびを追加し、タスクを追加するには拒否ポリシーがかかります。資源の枯渇の問題を防ぐことができ、円の配列があります。
2.5.2 LinkedBlockingQuene
リンクされたリストに基づいて、無制限のブロッキングキューは、実際には、上限は(Integer.MAX_VALUEの)です。これは、主なタスクは、タスクキューそれらに押し込まれていたであろうです。しかし、唯一のタスクを実行するためにコアスレッドを有効にして、緊急スレッドを起動しません。したがって、それはmaximumPoolSize corePoolSizeと一貫性を設定するのが最善です。
2.5.3 SynchronousQuene
これは、スレッドを待たねばならない課題になると、バッファキューのブロッキング作業ではありません。これは、新しいタスクがキャッシュされませんが、直接使用可能なスレッドが存在しない場合、スレッドの数がmaximumPoolSizeに達した場合、戦略を実行することを拒否し、新しいスレッドを作成し、このタスクを実行するようにスケジュールされ、入って来ています。
2.5.4 PriorityBlockingQueue
優先順位の無制限のブロッキングキューは、優先順位は、パラメータ比較によって達成されます。
2.6 ThreadFactory threadFactory
新しいスレッドを作成し、使用する工場では、スレッドがどうかなどデーモンスレッドとして、名前を設定するために使用することができます
2.7のRejectedExecutionHandlerハンドラ
**拒否ポリシー。タスクキューは、タスクの上限に達した場合、我々は政策を否定追加していく場合には、戦略を拒否することによって、新たなタスクを処理するために使用されます。**異なる方法が異なる拒否戦略を持って、4つのデフォルトポリシーを否定ありいるJDK:
ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务
使用3つのエグゼキューファクトリメソッド
3.1 newFixedThreadPool
評価:割り当ては知られているため、比較的時間のかかるタスク
// 核心线程数 == 最大线程数(没有救急线程被创建),因此也无需超时时间
// 阻塞队列是无界的,可以放任意数量的任务
Executors.newFixedThreadPool(5);
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
3.2 newCachedThreadPool
評価は:全体のパフォーマンスは、スレッドプールスレッドの数は、タスクに応じて量を増やしていきますで、上限、タスクが終了すると、アイドル状態のスレッドが1分後にリリースされているがありません。各タスクの状況をより集中的な、しかし、短い実行時間のためのタスクの数
// 核心线程数是 0, 最大线程数是 Integer.MAX_VALUE,救急线程的空闲生存时间是 60s,意味着
// 全部都是救急线程(60s 后可以回收)
// 救急线程可以无限创建
// 队列采用了 SynchronousQueue 实现特点是,它没有容量,没有线程来取是放不进去的(一手交钱、一手交货)
Executors.newCachedThreadPool();
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
3.3 newSingleThreadExecutor
// 希望多个任务排队执行。线程数固定为 1,任务数多于 1 时,会放入无界队列排队。任务执行完毕,这唯一的线程也不会被释放。
Executors.newSingleThreadExecutor();
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
これは、下で説明する必要があるスレッドプール(一つのスレッドだけ)とシングルスレッドの違いは何を作成するために、独自に作成する方法:
- タスクが何らかの救済せずに終了するために失敗した場合、自分でシングルスレッドのシリアルタスクを作成するだけでなく、正常な動作を保証するスレッドプールのスレッドプールを作成します。
スレッドプール(一つだけスレッド)を使用し、この方法は、差分を作成スレッドプールを作成Executors.newFixedThreadPool(1)を使用します。
-
番号()スレッドExecutors.newSingleThreadExecutorは常に1、変更することはできません
- ThreadPoolExecutorの特有のメソッドを呼び出すことができないのでFinalizableDelegatedExecutorServiceは、装飾的なモード、唯一の外部露出ExecutorServiceのインターフェースを適用しました
-
Executors.newFixedThreadPool(1)は、最初は1であり、後に変更することができます
- 外国露出がThreadPoolExecutorオブジェクトである、あなたは強いターン後に変更setCorePoolSizeメソッドを呼び出すことができます
タスクを送信4
// 执行任务
void execute(Runnable command);
// 提交任务 task,用返回值 Future 获得任务执行结果
<T> Future<T> submit(Callable<T> task);
// 提交 tasks 中所有任务
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException;
// 提交 tasks 中所有任务,带超时时间
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit) throws InterruptedException;
// 提交 tasks 中所有任务,哪个任务先成功执行完毕,返回此任务执行结果,其它任务取消
<T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException;
// 提交 tasks 中所有任务,哪个任务先成功执行完毕,返回此任务执行结果,其它任务取消,带超时时间
<T> T invokeAny(Collection<? extends Callable<T>> tasks,long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
5.閉じるスレッドプール
5.1シャットダウン
/*
线程池状态变为 SHUTDOWN
- 不会接收新任务
- 但已提交任务会执行完
- 此方法不会阻塞调用线程的执行
*/
void shutdown();
public void shutdown() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
checkShutdownAccess();
// 修改线程池状态
advanceRunState(SHUTDOWN);
// 仅会打断空闲线程
interruptIdleWorkers();
onShutdown(); // 扩展点 ScheduledThreadPoolExecutor
} finally {
mainLock.unlock();
}
// 尝试终结(没有运行的线程可以立刻终结,如果还有运行的线程也不会等)
tryTerminate();
}
5.2 shutdownNowの
/*
线程池状态变为 STOP
- 不会接收新任务
- 会将队列中的任务返回
- 并用 interrupt 的方式中断正在执行的任务
*/
List<Runnable> shutdownNow();
public List<Runnable> shutdownNow() {
List<Runnable> tasks;
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
checkShutdownAccess();
// 修改线程池状态
advanceRunState(STOP);
// 打断所有线程
interruptWorkers();
// 获取队列中剩余任务
tasks = drainQueue();
} finally {
mainLock.unlock();
}
// 尝试终结
tryTerminate();
return tasks;
}