Javaスレッド池詳細解:ThreadPool Exector、Exectors


オペレーティングシステムでは、スレッドは非常に重要なリソースであり、頻繁に大量のスレッドを作成して廃棄すると、システム性能を大幅に低下させます。Javaスレッド池の原理はデータベース接続池と似ています。目的はスレッド多重を実現し、頻繁にスレッドを作成して廃棄することを助けます。
ThreadPool Exector
ThreadPool Exectorはスレッド池のコアクラスです。まず、どのようにThreadPoolExectorを作成するかを見てください。以下はThreadPool Exectorでよく使われる構造方法です。
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue)
パラメータの紹介:
corePoolSize
コアスレッドの数は、スレッドが作成されたばかりの場合、スレッド数は0であり、新たなタスクを追加するたびに、スレッド数がcorePoolSizeに達するまで、オンラインプログラムで新しいスレッドを作成します。
work Que
列をブロックして、スレッドが実行中のスレッドの数がcorePoolSizeに達したら、executeを介して新しいタスクを追加するとワークQueキューに追加され、列の中に並んで実行を待っています。すぐに実行されません。
maximPoolSize
最大スレッド数は、workQueの列がいっぱいになっている時に、新しいタスクを放しられなくなり、またexecuteを通じて新しいタスクを追加すると、スレッド池はまた新しいスレッドを作成します。スレッド数はcorePoolSizeより大きいですが、maximPoolSizeを超えないです。
keep Alive Timeとunit
スレッドの池のスレッド数がworkQueより大きい場合、スレッドの空き時間がkeep Alive Timeより大きいと、スレッドは破壊されます。unitはkeep Alive Timeの時間単位です。
スレッドを追加するタスクの流れをまとめます。
  • スレッドプールが作成されたばかりです。スレッドの数は0です。
  • executeに新しいタスクを追加すると、オンラインプログラムで新しいスレッドを作成します。
  • スレッド数がcorePoolSizeに達した時、新しいタスクを追加するとワークQueキューにジョブを配置します。
  • キューがいっぱいになったら、新しいタスクを追加すると新しいスレッドを作成し続けますが、スレッドの数はmaximPoolSizeを超えません。
  • スレッド数がmaximPoolSizeに達したら、新しいタスクを追加すると異常が発生します。
  • Exectors
    Exectorsは、いくつかのスレッド池を作成するためのツール方法を提供する。
    Exectors.newSingleThreadExector()
    ソースの実現:
    new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())
    corepoolSizeとmaximPoolSizeは全部1で、つまり固定サイズが1のスレッド池を作成しました。workQueはnew LinkedBlockingQueue<Runnable>()です。つまり、列のサイズはInteger.MAX_VALUEです。キューのサイズは制限されていません。
    これにより、この方法によって作成されたスレッド池は、毎回1つのスレッドしか同時に実行できず、複数のタスクが同時に提出された場合にも、1つずつ整列して実行されることができる。
    Exectors.newFixedThreadPool(int nThreads)
    ソースの実現:
    new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())
    同様のExecutors.newSingleThreadExecutor()も固定サイズのスレッドプールを作成したが、同時に実行するスレッドの数はnThreadsであることを指定することができる。
    Exectors.newCachedThreadPool()
    ソースの実現:
    new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>())
    corepoolSizeは0で、maximPoolSizeはInteger.MAX_VALUEです。無限大と見なすことができます。workQueはSynchronousQueです。Synch ronousQueは長さが0に制限されている列と考えられます。つまり、この列にタスクを追加するといつまでも満杯となります。
    これにより、この方法によって作成されたスレッド池はスレッドの数を制限するものではなく、毎回追加されたタスクはワークQueに入れずに直接実行され、主に提供される機能はスレッド多重であるが、スレッドの数を制御することはできないということが分かる。