1。はじめに
スレッドプールの合理的な使用は、3つの利点をもたらす可能性があります。最初:リソースの消費を削減します。作成されたスレッドを再利用することにより、スレッドの作成と破壊によって引き起こされる消費を減らします。 2番目:応答速度を改善します。タスクが到着すると、スレッドが作成された直後にタスクを実行できます。 3番目:スレッドの管理性を改善します。スレッドは希少なリソースです。無制限に作成された場合、彼らはシステムリソースを消費するだけでなく、システムの安定性を低下させます。スレッドプールを使用すると、統一された割り当て、チューニング、監視ができます。ただし、スレッドプールを合理的に使用するには、その原則をよく知っている必要があります。
2。スレッドプールの使用
執行者が提供する4種類のスレッド1. NewCachedThreadPoolは、キャッシュ可能なスレッドプールを作成します。スレッドプールの長さが処理のニーズを超えると、アイドルスレッドを柔軟にリサイクルできます。リサイクルがない場合は、新しいスレッドを作成します。 2. newfixedthreadpoolは、最大数のスレッドの並行性を制御できる固定長スレッドプールを作成し、超過スレッドがキューで待機します。 3. newscheduledthreadpoolは、時限で定期的なタスクの実行をサポートする固定長さのスレッドプールを作成します。 4.NewSingLethReadExecutorシングルスレッドスレッドプールを作成します。これは、一意のワーカースレッドを使用してタスクを実行し、すべてのタスクが指定された順序で実行されるようにします(FIFO、LIFO、優先度)。
1.NewCachedThreadPoolは、キャッシュ可能なスレッドプールを作成します。スレッドプールの長さが処理のニーズを超えると、アイドルスレッドを柔軟にリサイクルできます。リサイクルがない場合は、新しいスレッドを作成します。例は次のとおりです
executorservice executorservice = executors.newcachedthreadpool(); for(int i = 0; i <5; i ++){final int index = i; try {thread.sleep(index * 1000); } catch(arturnedexception e){e.printstacktrace(); } executorservice.execute(new runnable(){@override public void run(){system.out.println(thread.currentthread()。getname() + "、" + index);}}) Pool-1-Thread-1,0Pool-1-Thread-1,1,1,-Thread-1,2Pool-1-Thread-1,3Pool-1-Thread-1,42. newfixedthreadpoolは、最大数のスレッドの並行性を制御できる固定長スレッドプールを作成し、超過スレッドがキューで待機します。例は次のとおりです
executorservice sixedthreadpool = executors.newfixedthreadpool(4); for(int i = 0; i <5; i ++){final int index = i; fixedthreadpool.execute(new runnable(){@Override public void run(){try {system.out.println(thread.currentthread()。getName() + "、" + index); sweep(2000);} catch(interruptedexception e){e.printstrace(); pool-1-thread-1,0pool-1-thread-2,1pool-1-thread-3,2pool-1-thread-4,3pool-1-thread-1,43.NewscheduledThreadPool固定長のスレッドプールを作成し、サポートサイクルとタイミングタスクの例は次のとおりです。
ScheduleDexecutorservice ScheduleDthreadPool = executors.NewsCheduleDThreadPool(5); System.out.Println( "before:" + system.currenttimemillis()/1000); ScheduledThreadPool.schedule(new runnable(){@Override public void run(){system.out.println( "3秒間の遅延実行:" + system.currenttimemillis()/1000);}}、3、timeUnit.seconds); +System.CurrentTimeMillis()/1000); //コンソール情報前:1518012703After:1518012703 3秒間遅延:1518012706System.out.println( "before:" +system.currenttimemillis()/1000); runnable(){@override public void run(){system.out.println( "1秒後、" +system.currenttimemillis()/1000)、1、3、timeunit.seconds);コンソールメッセージ
前:1518013024
後:1518013024
1秒の遅延の後、3秒で1回実行:1518013025
1秒の遅延の後、3秒で1回実行:1518013028
1秒の遅延の後、3秒で1回実行:1518013031
4.EnewSingLethReadExecutorは、ワーカースレッドのみを使用してタスクを実行し、注文を確保する単一スレッドスレッドプールを作成します。例は次のとおりです
executorservice singlethreadexecutor = executors.newsinglethreadexecutor(); for(int i = 0; i <10; i ++){final int index = i; singlethreadexecutor.execute(new runnable(){@override public void run(){try {system.out.println(thread.currentthread()。getName() + "、" + index); sleap.sleep(2000);} catch(interrustedexception e){e.printstacktrace();};};};};コンソール情報
Pool-1-thread-1,0
Pool-1-thread-1,1
Pool-1-thread-1,2
pool-1-thread-1,3
Pool-1-thread-1,4
タスクをスレッドプールに送信します。 StreadPoolexecutorクラスのexecute()とsubmit()の違いは、実際にはエグゼクティアで宣言された方法です。 ThreadPoolexecutorに実装されています。この方法は、ThreadPoolexecutorのコア方法です。この方法により、タスクをスレッドプールに送信し、実行のためにスレッドプールに引き渡すことができます。
submit()メソッドは、executorserviceで宣言されたメソッドです。 AbstractExecutorServiceに実装されています。 ThreadPoolexecutorで書き直されていません。この方法は、タスクをスレッドプールに送信するためにも使用されます。ただし、execute()メソッドとは異なります。タスクの実行の結果を返すことができます。ソースコードを介してsubmit()メソッドの実装を確認すると、実際にはexected()メソッドが呼び出されたメソッドであることがわかりますが、将来を使用してタスクの実行結果を取得します。
/** * @Throws redjectedExecutionException {@inheritdoc} * @Throws nullpointerexception {@inheritdoc} */public future <? runnableFuture <void> ftask = newtaskfor(task、null); execute(ftask); ftaskを返します;}スレッドプールのクローズスレッドプールのシャットダウンまたはシャットダウンメソッドを呼び出すことでスレッドプールを閉じることができますが、その実装原則は異なります。シャットダウンの原則は、スレッドプールの状態を単純に設定して状態をシャットダウンし、タスクを実行していないすべてのスレッドを中断することです。 ShutDownNowの原則は、スレッドプールでワーカースレッドを通過し、スレッドの割り込み方法を1つずつ呼び出してスレッドを割り込むことです。そのため、割り込みに応答できないタスクは終了することはありません。 ShutdownNowは、最初にスレッドプールの状態を停止してから設定し、次にタスクを実行または一時停止しているすべてのスレッドを停止し、タスクが実行されるのを待つリストに戻ります。
これら2つのクロージングメソッドのいずれかが呼び出されている限り、Isshutdownメソッドはtrueを返します。すべてのタスクが閉じられている場合、スレッドプールが正常に閉じられていることを意味します。 iSterminaedメソッドを呼び出すと、trueが返されます。スレッドプールを閉じるために呼び出す方法については、スレッドプールに提出されたタスク特性によって決定される必要があります。通常、スレッドプールを閉じるためにシャットダウンが呼び出されます。タスクを実行する必要がない場合、ShutdownNowを呼び出すことができます。
3。スレッドプールの分析
プロセス分析:スレッドプールの主なワークフローを以下の図に示します:Javaスレッドプールのメインワークフロー
上記の図から、新しいタスクをスレッドプールに送信すると、スレッドプールの処理フローが次のとおりであることがわかります。
**ソースコード分析。 **上記のプロセス分析により、スレッドプールの動作原理を直感的に理解することができます。ソースコードを使用して、その実装方法を確認しましょう。スレッドプールは次のようにタスクを実行します。
public void execute(runnable command){if(command == null)throw new nullpointerexception(); int c = ctl.get(); if(workercountof(c)<corepoolsize){if(addworker(command、true))return; c = ctl.get(); } if(isrunning(c)&& workqueue.offer(command)){int recheck = ctl.get(); if(!isrunning(recheck)&& remove(command))reject(command); else if(workercountof(recheck)== 0)addworker(null、false); } else if(!addworker(command、false))reject(command);}ワーカースレッド。スレッドプールがスレッドを作成すると、スレッドをワーカースレッドにカプセル化します。ワーカーがタスクを実行した後、作業キュー内のタスクを実行するためにタスクを取得するために無限にループします。
上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。