javaスレッド池、アリはなぜExectorsを使用することができませんか?
6644 ワード
問題があるアリJavaコード仕様は、なぜExectorsを使用してスレッドを素早く作成することができないのですか? 以下のコード出力は何ですか?
B)0~5の順番が一致しないで5行出力します.
C)0
基礎
スレッド池とは?
スレッドプールはプールを通してリソースセットであり、どの池の役割も大同小異であり、主にリソースの作成、初期化のためのシステムオーバーヘッドを減らすために使用されます.
スレッドを作るのは「高い」ですか?
はい、そうです.スレッドを作成すると高価です.
システムの各プロセスには独自のメモリ空間があり、ライト級プロセスと呼ばれるスレッドも必要であることを知っています.
JVMにおいてデフォルトのスレッドは256 k〜1 M(32ビットまたは64ビットのオペレーティングシステムに依存)のメモリを使用する必要がある.(具体的な配列は詳しく調べません.JVMバージョンの変化に伴い、このデフォルト値はいつでも変更される可能性があります.スレッドがメモリを使う必要があることを知っているだけです.)
メモリ以外にもっとありますか?多くの文章はコンテキスト切り替え、CPUスケジュールを中に入れていますが、ここでスレッドスケジュールを入れないのは、睡眠中のスレッドがスケジュールされていないからです.睡眠中のスレッドでないと、スケジュールが必ず必要です.ただし、JVMでは、作成時のメモリ消費以外にもGCに圧力をかけます.スレッドを頻繁に作成する場合は、対応するスレッドを回収する必要があります.
スレッド池のメカニズム?
スレッドプールはスレッドを繰り返し利用する技術であり、スレッド池の主な仕組みは、スレッド数を一定に残して、何もしない時に眠らせ、アクティブにする時にはスレッドを持って実行することである.これらはスレッド池の実現に関わる具体的な戦略です.
どのようなよくある池がありますか?スレッド池 接続池(データベース接続、TCP接続など) BufferPool … Javaのスレッドの池
UML図(Java 8)
本当の実現類が見られます. ThreadPoolExector(1.5) Fork JoinPool(1.7) ScheduledThreadPool Exector(1.5) 今日は主に
Exectorsが提供する工場方法 newCachedThreadPool(ThreadPool Exector)
キャッシュ可能なスレッドを作成します.スレッドのサイズが処理に必要なスレッドを超えていると、空き領域(60秒実行しないタスク)のスレッドが回収され、ジョブ数が増加すると、新しいスレッドがスマートに追加されてタスクが処理されます.このスレッドプールはスレッドサイズに制限がありません.スレッドサイズはオペレーティングシステム(またはJVM)が作成できる最大スレッドサイズに完全に依存します.
newFixedThreadPool(ThreadPool Exector)
固定サイズのスレッドを作成します.スレッドがスレッドの最大サイズに達するまで、タスクを提出するたびにスレッドを作成します.スレッドのサイズが最大値に達するとそのまま維持されますが、あるスレッドが異常実行のために終了すると、スレッドの新しいスレッドが追加されます.
newSingleThreadExector(ThreadPool Exector)
単スレッドのスレッドを作成します.このスレッド池ではスレッドが一つしかなく、つまり単一スレッドのシリアルに相当するすべてのタスクを実行します.この唯一のスレッドが異常に終了すると、新しいスレッドが代替されます.このスレッドプールは、すべてのタスクの実行順序をタスクの提出順に実行することを保証します.
newScheduledThreadPool(ScheduledThreadPool Exector)
無限サイズのスレッドプールを作成します.このスレッドはタイミングと周期的にタスクを実行する必要があります.
newSingleThreadScheduledExector(ScheduledThreadPool Exector)
タイミングと周期的にタスクを実行するための単一スレッドを作成します.
newWork StealingPool(1.8 Fork JoinPool)
ジョブを作成して盗む
様々な工場法で使われているスレッド池実現類は最終的に3つしかなく、対応関係は以下の通りです.
工場の仕様
実装クラス
newCachedThreadPool
ThreadPool Exector
newFixedThreadPool
ThreadPool Exector
newSingle ThreadExector
ThreadPool Exector
newScheduledThreadPool
ScheduledThreadPoolExector
newSingleThreadScheduledExector
ScheduledThreadPoolExector
newWork Stealing Pool
Fork JoinPool
ThreadPool Exector
まず、 corePoolSize
コアプールのサイズは、
corePoolSizeに必要なスレッドはすぐに作成されたものではなく、タスクを提出した後に作成する必要がありますので、大量のキャッシュスレッド数があれば、まず空きタスクを提出してスレッドを最初に作成して、その後の実行効率を向上させてもいいです.
maximPoolSize
許可された最大スレッド数.
keep Alive Time
アイドルスレッドの空き時間は、コアスレッドが
ユニット
work Que
スレッドプールのタスクキュー.上述したスレッド池の主な役割は多重スレッドであり、タスクを処理するために必要なキューを保存する必要があります.これらのタスクを処理するために池のスレッドを使用するためには、タスクのキューが必要です.
threadFactory
スレッド池が新しいスレッドが必要であると判断した場合は、スレッドプロジェクトを介してスレッドを作成します.
ハンドル
ブロックされた時の処理プログラムを実行すると、スレッド池は処理できません.これはタスクのキューに関連しています.例えば、キューのサイズを指定できます.このサイズを超えたらどうすればいいですか?JDKはすでに私達のために考慮し、4つのデフォルト実装を提供しています.
以下はJDKのデフォルトの携帯戦略です. AbortPolicy(デフォルト)
CallerRunsPolicy
現在のスレッドがあるスレッドを呼び出して実行します.
DisccardPolicy
現在のタスクを直接破棄します.
DisccardOldest Policy
一番古いタスクを破棄して、現在のタスクをキューに追加します.
紛らわしいパラメータ:corePoolSize maximPoolSize workQue
タスクキュー、コアスレッド数、最大スレッド数の論理関係スレッド数がコアスレッド数より小さい場合、スレッドを作成します. スレッド数がコアスレッド数以上であり、タスクキューがいっぱいでない場合、タスクをタスクキューに入れる. スレッド数がコアスレッド数以上で、タスクキューがいっぱいです. スレッド数が最大スレッド数より小さい場合、スレッド を作成します.スレッド数が最大スレッド数に等しい場合、実行拒否処理プログラムを起動する(デフォルトの効果は、例外をスローし、ジョブを拒否する) .
この三つのパラメータはどのように設定すればいいですか?最適値がありますか?
JAVAは協働のサポートが不友好なので、スレッドとスレッドに大きく依存します.この値は最適な推薦がないため、業務ニーズに応じて設定する必要があります.異なるデマンド型は、複数の異なるスレッド池を作成して実行することができる.
問題1:アリ開発規範はなぜExectorsがスレッドを素早く作成することができないのですか?
参照先:https://github.com/alibaba/p3c
理由が見えるのは簡単です. newSingleThreadExector newFixedThreadPool
また、アリは、ユーザー定義
問題2:下記のコード出力は何ですか?
Cを選ぶべきです最大スレッド数は100であるが、コアスレッド数は1であり、ジョブキューは100である.スレッド数がコアスレッド数以上でタスクキューがいっぱいでない場合、タスクをタスクキューに入れます.この条件ですから、今後追加されるジョブはいずれも詰まります.
最後に
ThreadPool Exectorについての論理は実際に使うとちょっとおかしいです.スレッド池のスレッドは最大スレッド数を超えていないので、任務が長い間滞っている時に新しいスレッドを作成して処理することができますか?
ここではnewWork Stealing Pool、つまりFork JoinPoolをオススメします.仕事を盗むモードを取った.今後はFork JoinPoolについてみんなと話します.
転載先:https://www.cnblogs.com/ants/p/11343657.html
ThreadPoolExecutor executor = new ThreadPoolExecutor(
1, //corePoolSize
100, //maximumPoolSize
100, //keepAliveTime
TimeUnit.SECONDS, //unit
new LinkedBlockingDeque<>(100));//workQueue
for (int i = 0; i < 5; i++) {
final int taskIndex = i;
executor.execute(() -> {
System.out.println(taskIndex);
try {
Thread.sleep(Long.MAX_VALUE);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
A)0 1 2 3 4 5B)0~5の順番が一致しないで5行出力します.
C)0
基礎
スレッド池とは?
スレッドプールはプールを通してリソースセットであり、どの池の役割も大同小異であり、主にリソースの作成、初期化のためのシステムオーバーヘッドを減らすために使用されます.
スレッドを作るのは「高い」ですか?
はい、そうです.スレッドを作成すると高価です.
システムの各プロセスには独自のメモリ空間があり、ライト級プロセスと呼ばれるスレッドも必要であることを知っています.
JVMにおいてデフォルトのスレッドは256 k〜1 M(32ビットまたは64ビットのオペレーティングシステムに依存)のメモリを使用する必要がある.(具体的な配列は詳しく調べません.JVMバージョンの変化に伴い、このデフォルト値はいつでも変更される可能性があります.スレッドがメモリを使う必要があることを知っているだけです.)
メモリ以外にもっとありますか?多くの文章はコンテキスト切り替え、CPUスケジュールを中に入れていますが、ここでスレッドスケジュールを入れないのは、睡眠中のスレッドがスケジュールされていないからです.睡眠中のスレッドでないと、スケジュールが必ず必要です.ただし、JVMでは、作成時のメモリ消費以外にもGCに圧力をかけます.スレッドを頻繁に作成する場合は、対応するスレッドを回収する必要があります.
スレッド池のメカニズム?
スレッドプールはスレッドを繰り返し利用する技術であり、スレッド池の主な仕組みは、スレッド数を一定に残して、何もしない時に眠らせ、アクティブにする時にはスレッドを持って実行することである.これらはスレッド池の実現に関わる具体的な戦略です.
どのようなよくある池がありますか?
UML図(Java 8)
本当の実現類が見られます.
ThreadPoolExecutor
について話します.これも利用率の高い実現です.Exectorsが提供する工場方法
キャッシュ可能なスレッドを作成します.スレッドのサイズが処理に必要なスレッドを超えていると、空き領域(60秒実行しないタスク)のスレッドが回収され、ジョブ数が増加すると、新しいスレッドがスマートに追加されてタスクが処理されます.このスレッドプールはスレッドサイズに制限がありません.スレッドサイズはオペレーティングシステム(またはJVM)が作成できる最大スレッドサイズに完全に依存します.
固定サイズのスレッドを作成します.スレッドがスレッドの最大サイズに達するまで、タスクを提出するたびにスレッドを作成します.スレッドのサイズが最大値に達するとそのまま維持されますが、あるスレッドが異常実行のために終了すると、スレッドの新しいスレッドが追加されます.
単スレッドのスレッドを作成します.このスレッド池ではスレッドが一つしかなく、つまり単一スレッドのシリアルに相当するすべてのタスクを実行します.この唯一のスレッドが異常に終了すると、新しいスレッドが代替されます.このスレッドプールは、すべてのタスクの実行順序をタスクの提出順に実行することを保証します.
無限サイズのスレッドプールを作成します.このスレッドはタイミングと周期的にタスクを実行する必要があります.
タイミングと周期的にタスクを実行するための単一スレッドを作成します.
ジョブを作成して盗む
工場の仕様
実装クラス
newCachedThreadPool
ThreadPool Exector
newFixedThreadPool
ThreadPool Exector
newSingle ThreadExector
ThreadPool Exector
newScheduledThreadPool
ScheduledThreadPoolExector
newSingleThreadScheduledExector
ScheduledThreadPoolExector
newWork Stealing Pool
Fork JoinPool
ThreadPool Exector
まず、
ThreadPoolExecutor
の完全な構造関数を見ます.public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
コアプールのサイズは、
allowCoreThreadTimeOut
が設定されていない限り、スレッドが空き時間を超えても、この数のスレッドは少なくともプールに保持されます.corePoolSizeに必要なスレッドはすぐに作成されたものではなく、タスクを提出した後に作成する必要がありますので、大量のキャッシュスレッド数があれば、まず空きタスクを提出してスレッドを最初に作成して、その後の実行効率を向上させてもいいです.
許可された最大スレッド数.
アイドルスレッドの空き時間は、コアスレッドが
allowCoreThreadTimeOut
によってtrueになります.keepAliveTime
と協力して、keepAliveTime
の単位を設定する.例えば、ミリ秒、秒.スレッドプールのタスクキュー.上述したスレッド池の主な役割は多重スレッドであり、タスクを処理するために必要なキューを保存する必要があります.これらのタスクを処理するために池のスレッドを使用するためには、タスクのキューが必要です.
スレッド池が新しいスレッドが必要であると判断した場合は、スレッドプロジェクトを介してスレッドを作成します.
ブロックされた時の処理プログラムを実行すると、スレッド池は処理できません.これはタスクのキューに関連しています.例えば、キューのサイズを指定できます.このサイズを超えたらどうすればいいですか?JDKはすでに私達のために考慮し、4つのデフォルト実装を提供しています.
以下はJDKのデフォルトの携帯戦略です.
RejectedExecutionException
を投げると異常です.現在のスレッドがあるスレッドを呼び出して実行します.
現在のタスクを直接破棄します.
一番古いタスクを破棄して、現在のタスクをキューに追加します.
タスクキュー、コアスレッド数、最大スレッド数の論理関係
この三つのパラメータはどのように設定すればいいですか?最適値がありますか?
JAVAは協働のサポートが不友好なので、スレッドとスレッドに大きく依存します.この値は最適な推薦がないため、業務ニーズに応じて設定する必要があります.異なるデマンド型は、複数の異なるスレッド池を作成して実行することができる.
問題1:アリ開発規範はなぜExectorsがスレッドを素早く作成することができないのですか?
参照先:https://github.com/alibaba/p3c
理由が見えるのは簡単です.
workQueue
パラメータで直接new LinkedBlockingQueue()
を使用して、スレッドプールに無限にタスクを追加することができます.public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue();
}
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1,
1,
0L,
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue()));
}
スレッドプールに提出されたタスクが問題になります.例えば、sleepが恒久的であれば、メモリが漏洩し、最終的にはOOMが発生します.また、アリは、ユーザー定義
threadFactory
にスレッド名を設定することを推奨しています.問題2:下記のコード出力は何ですか?
Cを選ぶべきです最大スレッド数は100であるが、コアスレッド数は1であり、ジョブキューは100である.スレッド数がコアスレッド数以上でタスクキューがいっぱいでない場合、タスクをタスクキューに入れます.この条件ですから、今後追加されるジョブはいずれも詰まります.
最後に
ThreadPool Exectorについての論理は実際に使うとちょっとおかしいです.スレッド池のスレッドは最大スレッド数を超えていないので、任務が長い間滞っている時に新しいスレッドを作成して処理することができますか?
ここではnewWork Stealing Pool、つまりFork JoinPoolをオススメします.仕事を盗むモードを取った.今後はFork JoinPoolについてみんなと話します.
転載先:https://www.cnblogs.com/ants/p/11343657.html