スレッド多重化:スレッドプールノート
4914 ワード
スレッドの多重化:スレッドプール
スレッドプールの概要
スレッドプールとは?
JDBCに触れたことがある人は、データベース接続プール(例えば、c 3 p 0、Druidなど)を聞いたことがあるに違いありません.実は私の理解では、両者はあまり差がありません.しかし、スレッドプールに置かれているのはスレッドだけです.スレッドは軽量レベルのツールですが、作成と閉じるには時間がかかります.また、大量のスレッドがメモリリソースをプリエンプトします.盲目的な大量の資源はシステムに大きな圧力をもたらす.スレッドプールには、アクティブなスレッドが一定数存在します.スレッドの作成は、スレッドプールから取得された空きスレッドになります.スレッドを閉じると、スレッドプールにスレッドを返すようになります.
JDKによるスレッドプールのサポート
JavaはExecutorsを通じて5種類のスレッドプールを提供し、それぞれ:
newCachedThreadPool
キャッシュ可能スレッドプールを作成します.スレッドプールの長さが処理の必要を超えた場合、空きスレッドを柔軟に回収できます.回収可能でない場合は、新しいスレッドを作成します.newFixedThreadPool
スレッドプールを作成し、スレッドの最大同時数を制御し、超過したスレッドがキュー内で待機します.newScheduledThreadPool
定長スレッドプールを作成し、タイミングおよび周期的なタスク実行をサポートします.newSingleThreadExecutor
は、一意の作業スレッドでのみタスクを実行し、すべてのタスクが指定された順序(FIFO、LIFO、優先度)で実行されることを保証する単一スレッド化されたスレッドプールを作成します.newSingleThreadScheduledExcutor
単一スレッド化スレッドプールを作成し、タイミングおよび周期的なタスク実行をサポートします.スレッドプールの使用
まず簡単に使いますが、これは特別なところはありません.
newFixedThreadPool
が作成したスレッドプールが一定長であることを覚えておくだけで、スレッドの最大同時数を制御でき、超えたスレッドはキューで待機します.newCachedThreadPool
で作成されたスレッドプールは無限大であり、2番目のタスクを実行するたびに最初のタスクが完了すると、新しいスレッドを作成するのではなく、最初のタスクを実行するスレッドが多重化されます.タイミングタスク
newScheduledThreadPool
は、タイミングおよび周期的なタスク実行をサポートし、そのソースコードを表示します.主に以下の3つの方法があります.scheduleAtFixedRate()とscheduleWithFixedDelay()の違い
= +
に厳格に従います.タスクに異常が発生した場合、後続のすべてのサブタスクはスケジュールを停止します.そのため、異常がタイムリーに処理され、周期的なタスクの安定したスケジューリングに条件を提供することを保証しなければならない.
スレッドプールのレコードについて
ポリシーの拒否
スレッドプールを作成するコアクラスThreadPoolExecutorには、拒否ポリシーを指定するパラメータがあります.拒否ポリシーは、システムの過負荷運転時の救済策であり、通常は圧力が大きすぎるため、つまりスレッドプールのスレッドが切れ、待機キューがいっぱいになっていることです.JDKは4つの拒否ポリシーを提供しています.
スレッド拡張
ThreadPoolExecutor
は拡張可能なスレッドプールであり、beforeExecute()
、afterExecute()
、およびterminated()
がスレッドを制御することができる.protected void beforeExecute(Thread t, Runnable r) { }
protected void afterExecute(Runnable r, Throwable t) { }
protected void terminated() { }
これは3つの
protected
の空の方法で、サブクラスを拡張することができることを明らかにしています.*タスクを実行するスレッドでは、beforeExecute
およびafterExecute
などのメソッドが呼び出されます.これらのメソッドでは、ログ、タイミング、監視、または統計収集の機能を追加することもできます.*正常に動作しても、例外が放出されても、afterExecute
が呼び出されます.ただし、Eorrorを投げ出すと、メソッドは呼び出されません.またはbeforeExecute
がRuntimeException
を投げ出すと、タスクは実行されず、このメソッドも呼び出されません.*terminated
については、オンライン・スレッド・プールがクローズを完了した場合(すべてのタスクが完了し、すべてのワーカー・スレッドがクローズされた場合)、Executor
がライフサイクルで割り当てた様々なリソースを解放するほか、情報通知、ログ・レコードなどの機能も実行できます.補足
Future future = pools.submit(new Thread());
future.get();
newThread(Runnable r)
で取得できます).Ncpu = CPU
Ucpu = CPU ,0 <= Ucpu <= 1
W/C =
, :
Nthreads = Ncpu * Ucpu * ( 1 + W/C )