Java ThreadPoolExecutor
@author:Jingdai
@date:2020.11.03
最近、本によく出てくる「Java並行プログラミング実践戦闘」という本を読んだの
ThreadPoolExecutor
ですが、あまり馴染みがないので、勉強して簡単にまとめました。
基本概念
ThreadPoolExecutor
このクラスはスレッドプールです。前のこの本の「Javaコアテクノロジー、ボリューム1」を参照してください。Executors
メソッドなどのスレッドプールクラスの静的メソッドを作成するために導入できます。Executors.newCachedThreadPool()
実際にはThreadPoolExecutor
、コンストラクターを呼び出して作成することもできます。スレッドプールはい、後で導入されます。しかし、Alibaba Java開発マニュアルを読むとExecutors
、図1に示すように、クラスを使用してスレッドプールを作成することはできません。したがって
ThreadPoolExecutor
、クラスの使用法について学ぶことは非常に必要です。
コンストラクターパラメーター
ThreadPoolExecutor
このクラスには、スレッドプールを作成するための4つのコンストラクターがあります。それらは次のとおりです。
- ThreadPoolExecutor(int corePoolSize、int maximumPoolSize、long keepAliveTime、TimeUnit unit、BlockingQueue workQueue)
- ThreadPoolExecutor(int corePoolSize、int maximumPoolSize、long keepAliveTime、TimeUnit unit、BlockingQueue workQueue、RejectedExecutionHandlerハンドラー)
- ThreadPoolExecutor(int corePoolSize、int maximumPoolSize、long keepAliveTime、TimeUnit unit、BlockingQueue workQueue、ThreadFactory threadFactory)
- ThreadPoolExecutor(int corePoolSize、int maximumPoolSize、long keepAliveTime、TimeUnit unit、BlockingQueue workQueue、ThreadFactory threadFactory、RejectedExecutionHandlerハンドラー)
今、個々のパラメータは、ここで簡単に紹介されている最初の導入
corePoolSize
、maximumPoolSize
そしてworkQueue
、彼らは相互にされているとして、3つのパラメータを。
corePoolSize
:スレッドプール内のコアスレッドの数
maximumPoolSize
:スレッドプール内のスレッドの最大数
workQueue
:スレッドプールによって使用されるブロッキングキュー。ここでは主にその長さに関係しますまず想定さ
corePoolSize
、maximumPoolSize
及びworkQueue
長さが0よりも整数大きいです。task
以下に示すように、4つのケースで新しいタスクが到着します。
- スレッドプール内のスレッド数が<の
corePoolSize
場合、新しいコアスレッドが作成され、タスクが実行のためにスレッドプールに渡されます。- スレッドプール内のスレッド数> =
corePoolSize
であり、ブロッキングキューworkQueue
がいっぱいでない場合、新しいタスクはブロッキングキューに配置されて待機します。- スレッドプール内のスレッド
corePoolSize
数> =およびスレッドプールスレッド数<でmaximumPoolSize
、キューのブロックworkQueue
がいっぱいになると、新しい非コアスレッドが作成され、委任されたタスクが実行されます。- スレッドプールスレッドの数=の
maximumPoolSize
場合、ブロッキングキューworkQueue
がいっぱいである間、タスクは拒否されます。彼は拒否しました。特定の処理は後で導入されます。注:
workQueue
キューが無限であるときにブロックキューが設定されている場合(たとえば、事前定義されたボリュームLinkedBlockingQueueがない場合)、それmaximumPoolSize
は役に立ちません。が終了するcorePoolSize
と、タスクは常にブロッキングキューに追加されますが、ブロッキングキューがいっぱいではない場合、非コアスレッドが作成されることはありません。
keepAliveTime
:スレッドキープアライブ時間
unit
:スレッドが存続する時間の単位スレッドプール内のスレッド数がを超える
corePoolSize
と、超過スレッドアイドル時間が上記パラメータで設定した時間を超えると破棄されます。デフォルトでは、corePoolSize
時間の経過に伴うプール内のスレッド数の場合にのみ、この戦略が実装allowCoreThreadTimeOut(boolean)
されますが、ポリシーメソッドに設定することでコアスレッドも適用されます。
handler
:タスクプロセッサを拒否しますスレッドプールが閉じているか、スレッドプールの容量がいっぱい(
workQueue
いっぱいmaximumPoolSize
で、プール内のスレッドの数が)である場合、タスクをスレッドプールに送信すると、タスクプロセッサの作業が拒否されます。4つの事前定義された拒否ハンドラーがあります。
ThreadPoolExecutor.AbortPolicy
:デフォルトで拒否されたプロセッサRejectedExecutionException
。タスクの例外時にスローすることを拒否しました。ThreadPoolExecutor.CallerRunsPolicy
:タスクを送信するスレッドに、送信されたタスクを単独で実行させます。たとえば、メインスレッドがタスクをスレッドプールに送信し、スレッドプールによって拒否された場合、メインスレッドはそれ自体でタスクを実行します。ThreadPoolExecutor.DiscardPolicy
:実行できないタスクを直接破棄します。ThreadPoolExecutor.DiscardOldestPolicy
:スレッドプールが閉じられていない場合、ブロックキュースレッドプールworkQueue
は最初のタスクを破棄してから、再実行を試みます。
その他の関連する方法
上記はコンストラクターの関連パラメーターについて説明していますが、同時に、スレッドプールの作成後に、関連パラメーターを変更することもできます。
getCorePoolSize()
とsetCorePoolSize(int corePoolSize)
名前からわかるように、スレッドプール内のコアスレッドの数を表示および変更できます
getMaximumPoolSize()
とsetMaximumPoolSize(int maximumPoolSize)
スレッドプール内のスレッドの最大数を表示および変更する
setKeepAliveTime(long time, TimeUnit unit)
スレッドが非アクティブの場合に破棄される期間を設定します
その他
Executors
本質的にスレッドプールを作成する上記の静的メソッドもThreadPoolExecutor
コンストラクターの呼び出しです。jdk8のソースコードを見てください。public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); } public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
ここでは本質が同じであることがわかります。したがって、この構築方法でスレッドプールを作成すると、スレッドプールのさまざまなパラメーターをより明確に知ることができます。
参照
- Java 8 API