システム内のスレッドを開始するコストは、オペレーティングシステムとの相互作用を伴うため、比較的高くなっています。スレッドプールを使用する利点は、パフォーマンスを改善することです。システムに多数の同時スレッドが含まれている場合、システムのパフォーマンスが急激に低下し、JVMがクラッシュすることさえあります。スレッドプールパラメーター内のスレッドの最大数は、システム内の同時スレッドの数を制御できます。回数を超えないようにします。
1.エグゼキューターファクトリークラスは、スレッドプールを生成するために使用されます。このファクトリークラスには、対応するスレッドプールを作成するための次の静的な工場メソッドが含まれています。作成されたスレッドプールは、executorserviceオブジェクトです。オブジェクトの送信方法または実行方法を実行して、対応する実行可能または呼び出し可能なタスクを実行します。スレッドプール自体は、Shutdown()メソッドを呼び出して、スレッドプールが不要になったときに停止します。メソッドを呼び出した後、スレッドプールはタスクを追加することを許可しなくなりますが、追加されたタスクがすべて実行されるまで死にません。
1。NewCachedThreadPool()は、キャッシュ機能を備えたスレッドプールを作成し、スレッドプールのタスク(実行可能または呼び出し可能なオブジェクト)によって作成されたスレッドを提出します。実行が完了した場合、後で実行する必要があるタスクを使用するために、CachedThreadPoolにキャッシュされます。
java.util.concurrent.executorservice; Import java.util.concurrent.executors; public class cachethreadpool {static classタスク実装{@override public void run(){system.out.println(this + "" + swrews.currentRead()。 thread.currentthread()。getallStackTraces()。size()); }} public static void main(string [] args){executorservice cachethreadpool = executors.newcachedthreadpool(); //最初に3つのタスクをスレッドプールに追加します(int i = 0; i <3; i ++){cachethreadpool.execute(new Task()); } // 3つのスレッドが実行されたら、スレッドプールに3つのタスクを再度追加してください{thread.sleep(3000); } catch(arturnedexception e){e.printstacktrace(); } for(int i = 0; i <3; i ++){cachethreadpool.execute(new Task()); }}}実行結果は次のとおりです。
cachethreadpool $ task@2d312eb9 pool-1-thread-1 allstacktracesマップサイズ:7cachethreadpool $ task@59522b86 pool-1-thread-3 allstacktracesマップサイズ:7cachethreadpool $ tax Pool-1-Thread-3 AllStackTracesマップサイズ:7CachethreadPool $ TASK@256D5600 Pool-1-Thread-1 AllStackTracesマップサイズ:7CachethreadPool $ TASK@7D1C5894 Pool-1-Thread-2 AllStackTracesマップサイズ:7
スレッドプールのスレッドオブジェクトは、新しいタスクが実行されるとキャッシュされ、再利用されます。ただし、多くの並行性がある場合、キャッシュスレッドプールは引き続き多くのスレッドオブジェクトを作成します。
2。NEWFIXEDTHREADPOOL(int nthreads)は、スレッドで再利用できるスレッド数が指定されたスレッドプールを作成します。
java.util.concurrent.executorservice; Import java.util.concurrent.executors; public class sixtthreadpool {static classタスク実装runnable {@override public void run(){system.out.println(this + "" " + swrews.currentread() thread.currentthread()。getallStackTraces()。size()); }} public static void main(string [] args){executorservice sixtthreadpool = executors.newfixedthreadpool(3); //最初に3つのタスクをスレッドプールに追加します。 } // 3つのスレッドが実行されたら、スレッドプールに3つのタスクを再度追加してください{thread.sleep(3); } catch(arturnedexception e){e.printstacktrace(); } for(int i = 0; i <3; i ++){sixtthreadpool.execute(new Task()); }}}実行結果:
sixedthreadpool $ task@7045c12d pool-1-thread-2 allstacktracesマップサイズ:7fixedthreadpool $ task@50fa0bef-1-thread-2 allstacktracesマップサイズ:7fixedthreadpool $ task@ccb1870 pool-1-thread-2 allstacktracesマップAllstacktracesマップサイズ:7fixedthreadpool $ task@5bdeff18 pool-1-thread-2 allstacktracesマップサイズ:7fixedththreadpool $ task@7d5554e1-thread-1 Allstacktracesマップサイズ:7fixedthreadpool $ task@244468092 Pool-1-thread-3-3-thread-3-3-Thread-3 AllStacktraces Mapサイズ: 7fixedthreadpool $ task@fa7b978 pool-1-thread-2 allstacktracesマップサイズ:7
3。NewsIngLethReadExecutor()、単一のスレッドのみを備えたスレッドプールを作成します。
4。NewSheduledThreadPool(int corepoolsize)は、指定された数のスレッドを備えたスレッドプールを作成し、指定された遅延後にスレッドを実行できます。また、Shutdown()を呼び出してスレッドプールを閉じることができることを知って、一定期間にスレッドを繰り返すこともできます。
例は次のとおりです。
java.util.concurrent.executors; import java.util.concurrent.scheduledexecutorservice; Import java.util.concurrent.timeunit; public class scheduledthreadpool {静的クラスタスクは実行可能{@Override public void un(){@override public void( System.CurrentTimeMillis() + "" + thread.CurrentThread()。getName() + "AllStackTracesマップサイズ:" + thread.currentThread()。getAllStackTraces()。サイズ()); }} public static void main(string [] args){scheduledexecutorservice scheduleedexecutorservice = executors.newscheduledthreadpool(3); ScheduleDexecutorservice.schedule(new Task()、3、TimeUnit.seconds); ScheduleDexecutorservice.scheduleatfixedrate(new Task()、3、5、TimeUnit.seconds); {thread.sleep(30 * 1000); } catch(arturnedexception e){e.printstacktrace(); } ScheduleDexecutorservice.shutdown(); }}操作結果は次のとおりです。
時間1458921795240 Pool-1-Thread-1 AllStackTracesマップサイズ:6time 1458921795241 AllstackTracesマップサイズ:6time 1458921800240 Pool-1458921800240 Pool-1-Thread-1 AllStackTraces Map Size:7time 1458921805240 Pool-1-Thread-1-7ted-1- 1458921810240 Pool-1-Thread-1 Allstacktracesマップサイズ:7time 1458921815240 Pool-1-Thread-1 AllStackTracesマップサイズ:7時間1458921820240 Pool-1-Thread-1 AllStackTracesマップサイズ:7
実行時間からわかるように、タスクは5秒のサイクルで実行されます。
5。NEWSINGLETHREADSCHEDULEDEXECUTOR()は、 1つのスレッドのみのスレッドプールを作成し、NewsCheduledThreadPool(1)を呼び出します。
2。ForkjoinpoolとForkjointask
Forkjoinpoolは、Executorserviceの実装クラスです。タスクを並列コンピューティングで複数の小さなタスクに分割し、複数の小さなタスクの計算結果を合計計算結果に組み合わせることをサポートします。 2つのコンストラクターがあります
forkjoinpool(int parlelishisis)は、並列性スレッドを含むforkjoinpoolを作成します。
forkjoinpool()は、runtime.abailableprocessors()メソッドの返品値を並列性パラメーターとして使用して、forkjoinpoolを作成します。
ForkJointaskは、平行で合併できるタスクを表します。これは、将来のインターフェイスを実装する抽象クラスです。 2つの抽象的なサブクラスがあり、返品値のないタスクの再発と戻り値を持つ再回収を表します。独自のオブジェクトを実装するための特定のニーズに応じて、これら2つの抽象クラスを継承し、実行するためにForkjoinpoolの送信方法を呼び出すことができます。
再発の例は次のとおりで、0〜300の数値の並列出力を実装します。
java.util.concurrent.forkjoinpool;インポートjava.util.concurrent.recursiveaction; Import java.util.current.timeunit; public class actionforkjointask {static class printtaskは再帰的{private static final int threshold = 50;プライベートイントスタート;プライベートインクトエンド; public Printtask(int start、int end){this.start = start; this.end = end; } @Override Protected void compute(){if(end -start <threshold){for(int i = start; i <end; i ++){system.out.println(thread.currentthread()。getName() + "" + i); }} else {int middle =(start + end) / 2; printtask left = new Printtask(Start、Middle); printtask right = new Printtask(Middle、End); left.fork(); right.fork(); }}} public static void main(string [] args){forkjoinpool pool = new forkjoinpool(); pool.submit(new Printtask(0、300)); try {pool.awaittermination(2、timeunit.seconds); } catch(arturnedexception e){e.printstacktrace(); } pool.shutdown(); }}小さなタスクを分割した後、タスクのfork()メソッドを呼び出し、並行して実行するためにforkjoinpoolに追加します。
Recursivetaskの例は、合計する100の整数の並列計算を実装します。 20個ごとに分割し、結果を取得するためにそれらを合計し、最後に最終結果にマージします。
java.util.randomをインポート;インポートjava.util.concurrent.executionexception; Import java.util.concurrent.forkjoinpool; Import java.util.concurrent.future; Import java.util.util.concurrent.recursivetask; Privateforkjointask {intec caltask {statec caltask {statec caltask静的最終intしきい値= 20; private int arr [];プライベートイントスタート;プライベートインクトエンド; public caltask(int [] arr、int start、int end){this.arr = arr; this.start = start; this.end = end; } @Override Protected Integer compute(){int sum = 0; if(end -start <threshold){for(int i = start; i <end; i ++){sum+= arr [i]; } system.out.println(thread.currentthread()。getname() + "sum:" + sum);返品額; } else {int middle =(start + end) / 2; caltask left = new caltask(arr、start、middle); caltask right = new caltask(arr、middle、end); left.fork(); right.fork(); return left.join() + right.join(); }}} public static void main(string [] args){int arr [] = new int [100]; RANDOM RANDOM = new Random(); int total = 0; for(int i = 0; i <arr.length; i ++){int tmp = random.nextint(20); Total +=(arr [i] = tmp); } system.out.println( "合計" +合計); forkjoinpool pool = new forkjoinpool(4); future <integer> future = pool.submit(new caltask(arr、0、arr.length)); try {System.out.println( "cal result:" + future.get()); } catch(arturnedexception e){e.printstacktrace(); } catch(executionException)e){e.printstacktrace(); } pool.shutdown(); }}実行結果は次のとおりです。
合計912forkjoinpool-1-worker-2 sum:82forkjoinpool-1-worker-2 sum:123forkjoinpool-1-worker-2 sum:144forkjoinpool-1-worker-3 sum:119forkjoinpool-1-worker-2 sum:106forkjoinpool-1-worker-2:128forkjoinpool-1-worker-2合計:121forkjoinpool-1-worker-3合計:89cal結果:912
サブタスクが実行されたら、タスクのJoin()メソッドを呼び出してサブタスク実行結果を取得し、それを追加して最終結果を取得します。