序文
以前の記事は、バックエンドサービスデータベースとマルチスレッド並列処理の最適化、および変換の前後の擬似コードロジックの例に焦点を当てています。もちろん、最適化は無限です。前世代の植物の木とその後の世代は日陰を楽しんでいます。開発者として、私たちは巨人の肩に立っているので、より最適化されたプログラムを書く必要があります。
スプリングブート開発ケースjdbctemplateバッチ操作
スプリングブート開発ケース:CountDownLatchマルチタスク並列処理
改修
理論的には、スレッドが多いほど、プログラムがより速くなる可能性がありますが、実際に使用すると、スレッド自体の作成と破壊のリソース消費、およびオペレーティングシステム自体を保護する目的を考慮する必要があります。通常、スレッドを特定の範囲に制限する必要があり、スレッドプールがこの役割を果たします。
プログラムロジック
マルチタスクパラレル +スレッドプールProcess.png
写真によって解決できる問題は、できるだけ少ないはずです。もちろん、根本的な原則は、誰もが覚えて理解する必要があります。
Javaスレッドプール
Javaは、エグゼキューターを通じて4種類のスレッドプールを提供します。
アドバンテージ
コード実装
方法1(CountDownLatch)
/***マルチタスクパラレル +スレッドプール統計*作成時間2018年4月17日*/public class statsdemo {final static simpledateformat sdf = new simpledateFormat( "yyyy-mm-dd hh:mm:ss");最終的な静的文字列starttime = sdf.format(new date()); / ** * IO集約型タスク=一般的に2 * CPUコアの数(多くの場合、スレッドで:データベースデータの相互作用、ファイルアップロードとダウンロード、ネットワークデータ送信など) runtime.getRuntime()。利用可能なProcessors(); /*** public threadpoolexecutor(int corepoolsize、int maximumpoolsize、long keepalivetime、* timeunit unit、blockingqueue <runnable> workqueue)* corepoolsizeは、コアスレッドの数を指定するために使用されます。スレッドプールのキュー、およびまだ実行されていないスレッドは、キュー*キューの長さを監視して、キューの境界*不適切なスレッドプールサイズが処理速度を遅くし、安定性を低下させ、メモリの漏れにつながることを確認します。構成されたスレッドが少なすぎると、キューは大きくなり続け、メモリを消費しすぎます。 *そして、あまりにも多くのスレッドがコンテキストの切り替えにより頻繁にシステム全体の速度を遅くし、同じ最終結果が達成されます。キューの長さは非常に重要であり、スレッドプールが圧倒された場合、新しいリクエストを一時的に拒否できるように境界を築く必要があります。 * executorserviceのデフォルトの実装は、固定されていないLinkedBlockingQueueです。 */ private static poolexecutor executor = new threadpoolexecutor(corepoolsize、corepoolsize+1、10l、timeunit.seconds、new linkedblockingqueue <runnable>(1000)); public static void main(string [] args)arturtedexception {countdownlatch latch = new CountDownLatch(5); // execute method executor.execute(new stats( "task a"、1000、latch))を使用します。 executor.execute(新しい統計( "タスクB"、1000、ラッチ)); executor.execute(新しい統計( "タスクC"、1000、ラッチ)); executor.execute(new Stats( "タスクD"、1000、ラッチ)); executor.execute(new Stats( "Task E"、1000、latch)); latch.await(); // system.out.println( "すべての統計タスクの実行が完了するために全員のタスクが終了するのを待ちます:" + sdf.format(new date())); } static class statsは実行可能{string statsname; intランタイム; CountDownLatchラッチ; public stats(string statsname、int runtime、countdownlatch latch){this.statsname = statsname; this.runtime = runtime; this.latch = latch; } public void run(){try {system.out.println(statsname+ "do stats begin at"+ starttime); //タスク実行時間swrep.sleep(runtime)をシミュレート; system.out.println(statsname + "do stats at" + sdf.format(new date())); latch.countdown(); //単一のタスクが終了すると、カウンターは1つ} catch(arternedexception e){e.printstacktrace(); }}}}方法2(将来)
/***マルチタスクパラレル +スレッドプール統計*作成時間2018年4月17日*/public class statsdemo {final static simpledateformat sdf = new simpledateFormat( "yyyy-mm-dd hh:mm:ss");最終的な静的文字列starttime = sdf.format(new date()); / ** * IO集約型タスク=一般的に2 * CPUコアの数(多くの場合、スレッドで:データベースデータの相互作用、ファイルアップロードとダウンロード、ネットワークデータ送信など) runtime.getRuntime()。利用可能なProcessors(); /*** public threadpoolexecutor(int corepoolsize、int maximumpoolsize、long keepalivetime、* timeunit unit、blockingqueue <runnable> workqueue)* corepoolsizeは、コアスレッドの数を指定するために使用されます。スレッドプールのキュー、およびまだ実行されていないスレッドは、キュー*キューの長さを監視して、キューの境界*不適切なスレッドプールサイズが処理速度を遅くし、安定性を低下させ、メモリの漏れにつながることを確認します。構成されたスレッドが少なすぎると、キューは大きくなり続け、メモリを消費しすぎます。 *そして、あまりにも多くのスレッドがコンテキストの切り替えにより頻繁にシステム全体の速度を遅くし、同じ最終結果が達成されます。キューの長さは非常に重要であり、スレッドプールが圧倒された場合、新しいリクエストを一時的に拒否できるように境界を築く必要があります。 * executorserviceのデフォルトの実装は、固定されていないLinkedBlockingQueueです。 */ private static poolexecutor executor = new threadpoolexecutor(corepoolsize、corepoolsize+1、10l、timeunit.seconds、new linkedblockingqueue <runnable>(1000)); public static void main(string [] args)throws arturnedexception {list <future <string >> resultlist = new arrayList <future <string >>(); //非同期タスクを送信し、future resultlist.add(executor.submit(new stats( "task a"、1000)))として返品値を取得します); resultlist.add(executor.submit(new Stats( "タスクB"、1000))); resultlist.add(executor.submit(new Stats( "タスクC"、1000))); resultlist.add(executor.submit(new Stats( "タスクD"、1000))); resultlist.add(executor.submit(new Stats( "Task E"、1000))); //(future <string> fs:resultList){try {system.out.println(fs.get())のトラバーサルタスクの結果; //各ラインタスクの結果を印刷して、future.get()を呼び出してメインスレッドをブロックし、非同期タスクの返された結果を取得し、catch(curtrededexception e) } catch(executionException e){e.printstacktrace(); }最後に{//一度起動して、以前に送信されたタスクを実行しますが、新しいタスクを受け入れないでください。閉じた場合、コールには他に効果がありません。 executor.shutdown(); }} system.out.println( "すべての統計タスクが実行されます:" + sdf.format(new date())); }静的クラス統計は、呼び出し可能な<string> {string statsname; intランタイム; public stats(string statsname、int runtime){this.statsname = statsname; this.runtime = runtime; } public string call(){try {system.out.println(statsname+ "do stats begin at"+ starttime); //タスク実行時間swrep.sleep(runtime)をシミュレート; system.out.println(statsname + "do stats at" + sdf.format(new date())); } catch(arturnedexception e){e.printstacktrace(); } return call(); }}}実行時間
上記のコードはすべて擬似コードであり、以下は2,000人以上の学生の実際のテスト記録です。
2018-04-17 17:42:29.284情報テストレコード81E51AB031EB4ADA92743DDF66528D82-SINGLE-THREADED SEVENALY実行、費やした時間:3797
2018-04-17 17:42:31.452情報テストレコード81E51AB031EB4ADA92743DDF66528D82-MULTI-THREADED PARALLELALS TASK、CONTER:2167
2018-04-17 17:42:33.170情報テストレコード81E51AB031EB4ADA92743DDF66528D82-MULTI-THREADED PARALLEL TASK + THREADプール、費やした時間:1717
上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。