[5] JUC。スレッドプール-ThreadPoolExecutor

スレッドプールを作成して三つの方法を分けることができます。

ThreadPoolExecutorオブジェクト、すなわちスレッドプールオブジェクトを作成する1 ThreadPoolExecutorコンストラクタ。

構造のこの方法では、パラメータはデフォルト値を5、二つのパラメータでなければならない7つのパラメータの合計は、後に詳細を述べました。

トランスミッション:https://www.cnblogs.com/mussessein/p/11654022.html

2.エグゼキュータは、スレッドプールのオブジェクトを返さ。

この方法で作成された一般的なスレッドプールは4種類で、あなたもForkJoinPoolオブジェクトを作成することができます。

この方法は、4つの一般的なエグゼキュータ静的メソッドは、スレッドプールの目的は、良好なパッケージ化されたThreadPoolExecutor四種類を返すことによって、パッケージ化されると言うことができます。

トランスミッション:https://www.cnblogs.com/mussessein/p/11654120.html

3. ForkJoinPoolの並行処理フレームワーク

より小さなタスクに大きなタスクを分割した後、使用したフォークは使用し、同時に他の小さなタスク処理スレッドに分配することができる参加複数の処理スレッドの結果を集計することができ、これは、実際にはパーティションの考えです。

なぜ、スレッドプールを使用します。

スレッドプールを使用するメリット

  1. リソース消費を削減します。再利用は、リソースの消費を減らすために、スレッド、スレッドの作成と破棄を作成されています。 

  2. 応答効率を向上させます。ミッションが到着すると、スレッドの作成を待たずに、すぐに実行することができます。 

  3. スレッドには、管理性を向上させます。

  4. サーバーの過負荷を防ぎます。メモリ不足、CPUが枯渇します。

話題に:

ThreadPoolExecutor

運用ルールは、このメソッドを使用してより明確なスレッドプール、資源の枯渇の危険性を回避するために、スレッドプールを作成するのではなくエグゼキューを作成するには、このクラスを使用してみてください

私は、プロセス・スレッド・プールについてお話しましょう:

  1. まずコア・スレッド・プールには、実行します。

  2. コアプールは、待機キューに、いっぱいです。

  3. キューは、スレッドの最大数がいっぱいになるまで、外部のスレッドが拒否拒否され、新しいスレッドが作成され、いっぱいです。

最後に、コードがあるだろう非常に詳細なプロセス全体のスレッドプールを、実証!

コンストラクタを探します。

// 7引数のコンストラクタは、最初の5つのパラメータがなければなりません
公共 ThreadPoolExecutor(int型corePoolSize、
                           int型maximumPoolSize、
                           ロングkeepAliveTimeが、
                          TimeUnitでユニット、
                          BlockingQueueの <Runnableを> ワークキュー、    
                          ThreadFactory ThreadFactoryは、     // 書き込むことはできません 
                          )のRejectedExecutionHandlerハンドラを// 書き込むことはできません

4つのコンストラクタThreadPoolExecutorのパラメータ:

  • コアサイズのプールではなく、スレッドの最大数:corePoolSize

    • maximumPoolSize> corePoolSize

    • あなたがスレッドプールを作成した後、スレッドプール内のスレッドの数は後で、それがスレッドプール内のスレッドの数がcorePoolSizeに達したときに、タスクがに達するだろう、タスクを実行するためのスレッドを作成するためのタスクがある場合、0でありますバッファキューの中で

  • maximumPoolSize:スレッドプール内のスレッドの最大数を作成するには、スレッドプールを最も表してどのように多くのスレッド

  • keepAliveTimeが次の場合、タスクの実行を終了していないスレッドを維持するまでを占めますどのくらい

    • デフォルト:corePoolSizeスレッドよりも大きなスレッドプール内のスレッドの数だけ、keepAliveTimeがしかそのタイミング

    • アイドル時間は、スレッドkeepAliveTimeがより大きくなると、それが終了します

    • あなたはallowCoreThreadTimeOut(boolean)を呼び出すと、スレッドプール内のスレッドの数がcorePoolSizeよりも少ない、keepAliveTimeがで動作します

  • 単位:パラメータkeepAliveTimeが(ユニットの7種類)の時間単位

    TimeUnit.DAYS;               //  
    TimeUnit.HOURS;              // 時間の 
    TimeUnit.MINUTES;            //  
    TimeUnit.SECONDS;            //  
    TimeUnit.MILLISECONDS;       // ミリ秒 
    TimeUnit.MICROSECONDS;       // 繊細 
    TimeUnit.NANOSECONDS;        // NS
  • ワークキュー:ブロッキングキューを選択

    LinkedBlockingQueue;     // 一般的な、無制限のブロッキングキュー、メモリが不足しやすいは、Integer.MAX_VALUEに値のデフォルトを通過しない
    SynchronousQueue。
    ArrayBlockingQueue;
    PriorityBlockingQueue // プライオリティキュー
  • threadFactory:メインスレッドの作成に使用するスレッドファクトリ。この引数を渡さない場合、デフォルト:Executors.defaultThreadFactory()

  • RejectedExecutionHandlerハンドラ:拒否の方針タスク、以下の4つの値を処理するときに時を示します。

    ThreadPoolExecutor.AbortPolicy:あなたは、このパラメータは、デフォルトを渡さない場合

    // RejectedExecutionExceptionタスクを破棄し、例外をスローします。
    ThreadPoolExecutor.AbortPolicyは 
     // また、タスクを破棄しますが、例外をスローしません。
    ThreadPoolExecutor.DiscardPolicy 
     // (このプロセスを繰り返して)一番のタスクキューを破棄して、タスクを実行しようと
    ThreadPoolExecutor.DiscardOldestPolicyが
     // 呼び出し側のスレッドでタスクを処理 
    ThreadPoolExecutor.CallerRunsPolicy

  それ自体が実装されてもよい動作が定義され、スレッドプールのスレッドから拒否された後、のRejectedExecutionHandlerインターフェイスを実装:後ろデモ。

重要な方法のThreadPoolExecutor:

  • (Runnableをコマンド)を実行

    この方法により、スレッド・プールにジョブを送信することができ、実行するスレッドプールに引き渡さ

    実行されるこの方法では、スレッドの現在の数がcorePoolSizeよりも大きいか否かを決定します

    現在のスレッドcorePoolSizeの数よりも大きく、現在のスレッドプールはRUNNING状態である場合、このタスクがタスクキューバッファに追加されます

  • 提出する()

    内部コールexecute()メソッド

    このメソッドは、スレッド・プールにジョブを送信するために使用されているが、それは異なっており、execute()メソッド

    タスクの実行結果を得るために、将来の使用、タスクの実行結果を返すことが可能です

  • シャットダウン()

    スレッドプールを閉じ、スレッドプールは、新しいタスクを受け入れることができ、この時点で、しないそれが完成し、すべてのタスクを待ちます

  • shutdownNowの()

    スレッドプールを閉じ、スレッドプールがSTOP状態にある場合、スレッド・プールには、新しいタスクを受け入れることができない、と行われているタスクを終了しようとします

デモスレッドプールのプロセス:

パブリック クラスタスクが実装されたRunnable {
     プライベート文字列名を、
    パブリックタスク(文字列名){
         この .nameの= 名前。
    }
    @オーバーライド
    公共 ボイドラン(){
         しようと{
            Thread.sleep( 2000 );
        } キャッチ(InterruptedExceptionある電子){
            e.printStackTrace();
        }
    }
    @オーバーライド
    パブリック文字列のtoString(){
         戻り 、この.nameのを、
    }
}
/ **
 *書き換えのRejectedExecutionHandler
 *あなたが拒否されたスレッドプールのスレッドの動作をカスタマイズした後
 * / 
パブリック クラス MyRejectedHandlerは、実装のRejectedExecutionHandlerを{
    @オーバーライド
    公共 ボイドrejectedExecution(RunnableをR、ThreadPoolExecutorエグゼキュータ){
        System.out.println( "拒否:" + r.toString());
    }
}

/ **
 * ThreadPoolExecutorの例。
 *四個の重要なパラメータ、
 * RejectedHandlerクラスのRejectedExecutionHandlerの独自の定義を達成
 *マルチスレッドプロセス:
 * 1コアのプールに移動し、コア・プールが満杯になった場合、キューにスレッド
 * 2.キューがいっぱいになっている、スレッドの最大数まで、スレッドを作成していき
 * 3.スレッドの最大数がいっぱいになると、スレッドに従うことを拒否しました
 * / 
パブリック クラスThreadPoolDemo {

    パブリック 静的 ボイドメイン(文字列[]引数){
         / **
         *スレッドプールのパラメータを設定します。
         *コアのスレッド:2
         *最大スレッド:3
         *ブロッキングキューサイズ:5
         *拒否ポリシー:カスタム
         * / 
        ThreadPoolExecutor threadPoolExecutor = 新しいThreadPoolExecutor(
                 2、3、2000 
                TimeUnit.MILLISECONDS、新しい ArrayBlockingQueue(5)、新しいMyRejectedHandler());

        // メインスレッドを起動し、雌ねじ10個のサブフレームは、スレッドプールが追加開始 
        runTask =()のRunnable - > {

            以下のためにint型、iは10 <; I = 0 iは++ ){
                文字列名 = "Task_" + I;
                タスクのタスク = 新しいタスク(名);
                してみてください{
                    / **
                     *あなたがスレッドプールにスレッドを追加するたびに、スレッドプールの内部の状況を印刷します
                     * /
                    threadPoolExecutor.execute(タスク)。
                    System.out.println( "プールサイズ:" + threadPoolExecutor.getPoolSize()+
                            "キュー" + threadPoolExecutor.getQueue())。
                    System.out.println();
                } キャッチ(例外e){
                    System.out.println( "拒否:" +の名前)。
                }
            }
            してみてください{
                Thread.sleep( 1000年);
            } キャッチ(InterruptedExceptionある電子){
                e.printStackTrace();
            }
        }。
        スレッドスレッド = 新しいスレッド(runTask)。
        thread.start();
    }
}            

結果:

プールサイズ:1 、キュー[]
プールサイズ: 2 、キューが[]
 // ここでは、プールのコアはいっぱいあるし、キューにスレッド 
プールサイズ:2 、キュー[Task_2]
プールサイズ: 2 、キュー[Task_2、Task_3]
プールサイズ: 2 、キュー[Task_2、Task_3、Task_4]
プールサイズ: 2 、キュー[Task_2、Task_3、Task_4、Task_5]
プールサイズ: 2 、キューは[Task_2、Task_3、Task_4、Task_5、Task_6]
 // キューがいっぱいになっている、余分なスレッドであるスレッドプールにスレッドを作成し続けるが待っている、とカウントダウンkeepAliveTimeが 
プールサイズ:3 、キュー[Task_2、Task_3 、Task_4、Task_5は、Task_6]
 // スレッドの最大数は、スレッドが従うことを拒否した、フルである
拒否:Task_8
プールサイズ: 3 、キュー[Task_2、Task_3、Task_4、Task_5、Task_6]
拒否:Task_9
プールサイズ: 3、キュー[Task_2、Task_3、Task_4、Task_5、Task_6]

違いは()メソッドを実行し、()メソッドを提出実行

(1)の戻り値を必要としないジョブを送信するために使用される()メソッドを実行し、そのタスクが正常か否かをスレッドプールで実行されるかどうかを決定することは不可能です。

(2)提出()メソッドは、タスクを送信するために必要な値を返します。スレッドプールは、タスクが正常に実行されるかどうかを確認することができ、この将来のオブジェクトによって、未来型のオブジェクトが返されます、タスクが完了するまでのget()メソッド、get()メソッドのブロック、現在のスレッドの将来によって返された値を取得することができ、および使用get(long timeout,TimeUnit unit)方法現在のスレッドがすぐに戻った後、タスクを実行することが可能である。この時間が完了していないいくつかの時間のためにブロックされます。

おすすめ

転載: www.cnblogs.com/mussessein/p/11654022.html
おすすめ