図1は、スレッドプールの説明:
プロセッサユニット内の複数の実行スレッドの主な問題を解決するためにマルチスレッド技術は、それが大幅にプロセッサユニットの処理能力を増加させる、プロセッサユニットのアイドル時間を減らすことができます。
T1は、スレッドでタスクを実行するための時間T2をスレッド時間を作成し、T3は、スレッドの時間を破壊する:タスクを完了するために必要なサーバー時間があるとします。
場合:T1 + T3がT2よりもはるかに大きい、スレッドプールは、サーバのパフォーマンスを向上させるために用いることができます。
:スレッドプールは、4つの基本的なコンポーネントで構成され
、新しいタスクを追加し、スレッドプールの作成など、スレッドプール、スレッドプールの破壊を作成および管理するために使用される:1、スレッドプールマネージャ(ThreadPoolの)
2、ワーカースレッド(PoolWorker):スレッドプール、いかなるタスクが待ち状態で存在しない場合には、あなたが作業サイクルを実行することができます;
3、タスクインターフェイス(タスク):各タスクは、スレッドスケジューリングタスクの実装のために、実装しなければならない、それがメインの規定の作業です入口は、ジョブを終了すると、タスクなどの実行状態終了する;
4、タスクキュー(タスクキュー):タスクを格納するために処理されません。バッファリング機構を提供します。
スレッドプールは、短くしたりすることにより、サーバプログラムの性能を向上させる、T1、時間のT3技術を調整する方法に焦点を当てています。これT1、T3は、クライアントがサーバプログラムの処理を要求したときに、オーバーヘッドT1、T3のがないことを、スタートアッププログラムとサーバまたはいくつかのアイドル時間期間が終了して配置されています。
生産する時のスレッドプールT1、T3の期間を調整し、それはまた、大幅に作成されたスレッドの数、例を見て減らすだけでなく:
処理サーバに50000のリクエスト日を想定し、各要求は別々のスレッドの完了を必要とします。スレッドプールは、スレッドの数は、一般的に固定されているので、生成されたスレッドの合計数は、プール内のスレッドの数を超えないように、サーバーがスレッド50,000の合計数にこれらの要求を処理するスレッドプールを使用している場合。一般的なスレッドプールのサイズが50000よりもはるかに小さいです。だから、効率を高めるための要求を処理している間に50,000を作成するために時間を無駄にしないスレッドプールのサーバープログラムを使用しています。
コードの実装は、タスクインターフェイスを実装していませんが、Runnableオブジェクトを完了するために、スレッドプールマネージャ(ThreadPoolの)によって、スレッドプールマネージャ(ThreadPoolの)、物事の残りの部分に追加されます
- パッケージmine.util.thread。
- 輸入java.util.LinkedList;
- 輸入はjava.util.List;
- / **
- *スレッド・プール、スレッドマネージャ:基本的な情報を得るために、スレッド、タスク、破壊スレッド、スレッドを作成します
- * /
- パブリック 最終 クラスのThreadPool {
- //スレッドプールのデフォルトのスレッド数5
- プライベート 静的な int型worker_num = 5;
- //労働者
- プライベートWorkThread [] workThrads。
- //未処理のタスク
- プライベート 静的 揮発性の int型のfinished_task = 0;
- //タスクキュー、バッファとして、リストのスレッドセーフ
- プライベートリスト<Runnableを>タスクキュー= 新しいLinkedListは<Runnableを>();
- プライベート 静的ThreadPoolのスレッドプール。
- //スレッドプールのスレッドがデフォルトの数を持って作成
- プライベートのThreadPool(){
- この(5)。
- }
- //スレッドプール内のワーカースレッドの数のため、worker_numをスレッドプールを作成します
- プライベートのThreadPool(int型worker_num){
- ThreadPool.worker_num = worker_num。
- workThrads = 新しいWorkThread [worker_num]。
- 以下のために(INT iが= ; I <worker_num 0をI ++){
- workThrads [I] = 新しいWorkThread()。
- workThrads [I] .start(); //プール内のスレッドを開きます
- }
- }
- //シングルトンパターン、スレッドプールのスレッドのデフォルトの数を取得します
- パブリック 静的ThreadPoolのgetThreadPool(){
- リターンgetThreadPool(ThreadPool.worker_num)。
- }
- //シングルトンパターン、スレッドプールスレッドの指定された数を得るために、worker_num(> 0)は、作業スレッドプールの数であります
- // worker_num <= 0ワーカースレッド数のデフォルト値を作成します
- パブリック 静的ThreadPoolのgetThreadPool(int型worker_num1){
- IF(worker_num1 <= 0)
- worker_num1 = ThreadPool.worker_num。
- (スレッドプール==場合 はnull)
- スレッドプール= 新しいThreadPoolの(worker_num1)。
- スレッドプールを返します。
- }
- //タスクをのみ、タスクキューに追加され、タスクを実行する、とするとき、スレッドプールマネージャの実装は睡眠を与えています
- 公共 ボイドが{(Runnableをタスク)を実行します
- 同期(タスクキュー){
- taskQueue.add(タスク)。
- taskQueue.notify();
- }
- }
- //バッチ実行タスクは、タスクはタスクキューに追加され、スレッドプールマネージャの実装は、睡眠を与えているとき
- 公共 ボイド{(Runnableを[]タスク)を実行します
- 同期(タスクキュー){
- (:タスクのRunnable t)に対する
- taskQueue.add(T)。
- taskQueue.notify();
- }
- }
- //バッチ実行タスクは、タスクはタスクキューに追加され、スレッドプールマネージャの実装は、睡眠を与えているとき
- 公共 ボイドが{(一覧<Runnableを>タスク)を実行します
- 同期(タスクキュー){
- (:タスクのRunnable t)に対する
- taskQueue.add(T)。
- taskQueue.notify();
- }
- }
- //スレッドプール、すべてのタスクの場合、すべてのスレッドの破壊を保証する唯一の方法が完了している破壊、またはタスクが破壊を完了するまで待ちます
- 公共の 無効(破棄){
- しばらく(!taskQueue.isEmptyは()){ //は一切タスクの実行が存在しない場合が完了すると、それがスリープします
- {試します
- Thread.sleep(10)。
- } キャッチ(InterruptedExceptionある電子){
- e.printStackTrace();
- }
- }
- //労働者が働いて停止し、nullに設定されています
- 以下のために(INT iが= ; I <worker_num 0をI ++){
- workThrads [I] .stopWorker()。
- workThrads [I] = NULL;
- }
- スレッドプール= NULL;
- taskQueue.clear(); //ジョブキューを空にする
- }
- //ワーカースレッドの数を返します。
- 公共 INT getWorkThreadNumber(){
- worker_num返します。
- }
- //完了したタスクの数を返し、タスクだけの数のタスクキューが完了すると、タスクは、実用的な実装を完了しない場合があります
- 公共 INT getFinishedTasknumber(){
- finished_task返します。
- }
- //、タスクキューの長さを返します。すなわち、タスクの数は扱われません
- 公共 INT getWaitTasknumber(){
- リターンtaskQueue.size();
- }
- //カバーtoStringメソッドそのリターンスレッドプール情報:作業が完了しているスレッドの数とタスクの数
- @オーバーライド
- パブリック文字列のtoString(){
- リターン "WorkThread番号:" + worker_num + "の完成タスク番号:"
- + finished_task + "待ちタスクの数:" + getWaitTasknumber();
- }
- / **
- *インナークラス、スレッドの仕事
- * /
- プライベート クラスWorkThreadは {スレッドを拡張します
- //ワーカースレッドは、ワーカースレッドの終わりのために有効です
- プライベート ブールisRunning = はtrue。
- / *
- *キーああ、タスクキューが空でない場合は、タスクの実行を削除し、タスクキューが空の場合、待機
- * /
- @オーバーライド
- 公共 のボイドの実行(){
- 実行可能R = NULL;
- 一方、(isRunning){ このスレッドの実行方法の天然の端部は無用である場合、スレッドが無効であることを//注意
- 同期(タスクキュー){
- 一方、(taskQueue.isEmpty isRunning &&()){ //キューが空であります
- {試します
- taskQueue.wait(20)。
- } キャッチ(InterruptedExceptionある電子){
- e.printStackTrace();
- }
- }
- (もし!taskQueue.isEmpty())
- taskQueue.remove = R&LT(0); //タスクをフェッチ
- }
- IF(R!= NULL){
- r.run(); //タスクを実行します
- }
- finished_task ++;
- R = NULL;
- }
- }
- //ストップ作業、自然終わり、自然にrunメソッドを実行した後、スレッドように
- 公共 のボイドstopWorker(){
- = isRunning はfalse;
- }
- }
- }
テストコード:
- パッケージmine.util.thread。
- //テストスレッドプール
- パブリック クラスTestThreadPool {
- パブリック 静的 無効メイン(文字列[] args){
- //スレッドプールのスレッドを作成3
- ThreadPoolのT = ThreadPool.getThreadPool(3)。
- t.execute(新しいRunnableを[] { 新規タスク()、 新しいタスク()、 新しいタスク()})。
- t.execute(新しいRunnableを[] { 新規タスク()、 新しいタスク()、 新しいタスク()})。
- System.out.println(T)。
- t.destroy(); //すべてのスレッドの実行がDestoryは前に完了しています
- System.out.println(T)。
- }
- //タスククラス
- 静的 クラスタスク 実装Runnableを{
- プライベート 静的 揮発 私は= INT 1。
- @オーバーライド
- 公共 無効RUN(){ //タスクを実行します
- System.out.println("タスク" +(I ++)+ "完全");
- }
- }
- }
結果:
WorkThread番号:3完成したタスクの数: 0待ちタスク番号:6
タスク1が完了し
完了させるタスク2
3完了したタスクを
完了するためにタスク4
、タスク5の完全な
タスクの完了6
WorkThread番号:3完成したタスク番号: 6待ちタスクの数:0
分析:なしタスク・インターフェースがないので、スレッドプールので、任意のタスク定義から渡すことができ、正確に実際のタスクが完了しているかどうかを判断することはできません(このタスクを達成するための真の方法は、このタスクが完了し実行することです)、のみタスクが実行されているジョブキューから出てきたか、完了していることを知っています。
2、Javaのクラスライブラリは、スレッドプールの説明を提供します。
より強力な提供するために、Javaのスレッドプール、私は、スレッドプール内のライブラリを参照して、スレッドプールの動作原理を理解することは奇妙な感じではないだろうと信じています。