ConcurrentLinkedQueue同時キューの使用状況およびブロッキングキューLinkedBlockingQueue
Javaのマルチスレッドアプリケーションでは、キューの使用率が高い、生産および消費モデルの大部分のための選択のデータ構造は、キュー(FIFO)です。スレッドセーフなキューJavaはブロッキングキューBlockingQueueの、非ブロッキングキューの典型的な例の代表例である非ブロッキングブロッキングキューのキューに分けることができる提供してConcurrentLinkedQueue、ブロッキングまたはキューのキューを非ブロッキングに使用する実際の必要に応じて実用的なアプリケーションで。
注意:スレッドセーフとは何ですか?最初に明らか。同じコード、スレッドセーフなマルチスレッドアクセスは、不確定な結果が得られません。
パラレルおよび同時違い
図1は、並列実行が前進二人が保持され、このようなレースのように、両方のことをいう;
2、同時限られたリソースを指し、両方を交互に、道路などのリソースを使用してオン(単コアCPUリソースが)だけで、同時に一人を持っていた、いくつかは、後に行くにB、Bを与えて実行し続け、交換可能に使用さ、それは効率を改善することを目指して
LinkedBlockingQueue
LinkedBlockingQueue実装は生産者と消費者の最初の選択肢であり、FIFO及び他の特性を達成するために、スレッドセーフであるため、LinkedBlockingQueueは、指定された容量であることができるが、指定されていない、指定されていないことができ、デフォルトの最大値は、主に使用されるInteger.MAX_VALUEで、あります置くと方法を取るためにキューが消費されるまで、キューに入れた方法は、フルタイムのメンバーは、ブロックされているキューがメンバーに置かれるまで、空のキューにメソッドのブロックを取ります。
cn.threadパッケージ変更のため、 インポートjava.util.concurrent.BlockingQueue; インポートjava.util.concurrent.ExecutorService; インポートjava.util.concurrent.Executors; インポートjava.util.concurrent.LinkedBlockingQueue; / ** *マルチスレッドのシミュレーションは、生産を達成するために/コンシューマモデル * * @author林チンメーター * @version 1.0 2013年7月25日午後5時23分11秒 * / publicクラスBlockingQueueTest2 { / ** * *定義インストールAppleのバスケット * * / publicクラスバスケット{ 3個のリンゴを収容可能//バスケット ; BlockingQueueの<ストリング>バスケットLinkedBlockingQueue新しい新しい= <文字列>(3) //リンゴ、バスケットに 公共ボイド農産物()は例外:InterruptedExceptionをスロー{ //バスケットが位置バスケットまで、いっぱいになったときに、アップルに方法を入れ basket.put(「アップル」); } //消費りんごは、バスケットはから削除された スロー)(消費パブリック文字列例外:InterruptedException { //バスケットが空の場合は、アップルがあるまで取得(バスケットまで、りんごの方法を取り出し、このキューの除去ヘッド) 戻りbasket.take(); } } //メーカーアップル定義され たクラスを実装したRunnable {プロデューサ プライベートStringインスタンス、 プライベートバスケットバスケット、 公共プロデューサ(文字列インスタンス、バスケットバスケット){ this.instance =インスタンス; this.basket =バスケット; } 公共ボイドRUN(){ リンゴの// 試み{ しばらく(真の){ 公共消費(Stringインスタンス、バスケットバスケット){ System.out.println( "リンゴを生産する準備ができてプロデューサー:" +インスタンス); basket.produce(); System.out.printlnは(:+インスタンス"!リンゴの生産者は、完成生成する"); //スリープ300ミリ秒 のThread.sleep (300); } }キャッチ(InterruptedExceptionあるEX){ するSystem.out.printlnは( "プロデューサー中断"); } } } //アップル消費者定義 クラスの消費者を実装したRunnable { プライベート文字列インスタンス; プライベートバスケットバスケット; this.instance =インスタンス; this.basket =バスケット; } RUN無効パブリック(){ 試み{ (真の)しばらく{ //消費者のApple のSystem.out.println( "消費者がリンゴを消費する準備ができている:" +インスタンス); System.out.printlnは(basket.consume()); システム。 out.printlnを(+インスタンス"Appleは消費者支出を:!終了"); //睡眠1000ミリ秒 のThread.sleep(1000); } }キャッチ{(InterruptedExceptionあるEX) のSystem.out.println( "消費者中断"); } } } パブリック静的無効メイン(文字列[] args){ BlockingQueueTest2 =新しい新しいBlockingQueueTest2試験()。 //ロードされたバスケットを作成し、アップル バスケットバスケット= test.newバスケット(); ExecutorServiceのサービス= Executors.newCachedThreadPool(); プロデューサープロデューサー= test.newプロデューサー( "プロデューサー001"、バスケット); プロデューサーProducer2 = test.newプロデューサ( "プロデューサー002"、バスケット); 消費者の消費者の消費者test.new =( "消費者001"、バスケット); service.submit(プロデューサー); service.submit(Producer2); service.submit(消費者); / 5Sを実行している/プログラム、すべてのタスクが停止 //試し{ //のThread.sleep(1000年* 5); //}キャッチ(InterruptedExceptionあるE){ // e.printStackTrace(); //} // service.shutdownNow(); } }
ConcurrentLinkedQueue
ConcurrentLinkedQueueは、キューのセキュリティの実装です。キューの要素は、FIFO原理によって並べ替えられています。要素の一貫性を確保するために、CAS操作を使用。
LinkedBlockingQueueは、インターフェイスのBlockingQueueを実装スレッドセーフなブロッキングキューで、java.util.Queue BlockingQueueのインターフェイスをブロックするインターフェイスから継承し、メソッドを追加取得し、これらの2つの方法に基づいて、このインタフェースを置くキュー操作でありますバージョン。
cn.threadパッケージ; インポートjava.util.concurrent.ConcurrentLinkedQueue; インポートjava.util.concurrent.CountDownLatch; インポートjava.util.concurrent.ExecutorService; インポートjava.util.concurrent.Executors; publicクラスConcurrentLinkedQueueTest { プライベート静的ConcurrentLinkedQueue <整数> ConcurrentLinkedQueue新しい新しいキュー= <整数>(); //スレッドの数;プライベート静的int型カウント= 2 一つ以上を可能にする操作の集合までたCountDownLatch、同期助剤は、//他のスレッドで実行され、スレッドが待っています。 たCountDownLatch新しい新しいスタティックラッチ=プライベートたCountDownLatch(COUNT); パブリック静的無効メイン(文字列[] args){InterruptedExceptionあるスロー ロングTimeStart =にSystem.currentTimeMillisを(); ES = Executors.newFixedThreadPool ExecutorServiceの(4); ConcurrentLinkedQueueTest.offer(); {(; Iは数<I ++はI = 0の整数)ため es.submit(新しい新しいポーリング()); } latch.await(); //そのlatch.countDown()までメインスレッド(メイン)ブロックは、継続実行前にゼロである ; -のSystem.out.println(TimeStart)+ "MS" "時間コスト" +(のSystem.currentTimeMillis()) ; es.shutdown() } / ** *生産 * / パブリック静的ボイドオファー(){ (INT I = 0; I <100000; I ++の)のために{ Queue.offer(I); } } / ** *消費 * * @authorメートルチンリン * @version 1.0 2013年7月25日午前5時32分56秒下午 * / 静的クラスのポール実装したRunnable { ます。public void実行(){ //しばらく(queue.size()> 0){ しばらく(!queue.isEmpty() ){ System.out.printlnは(queue.poll())。 } latch.countDown()。 } } }
業績:
costtimeの2360ms
スイッチの後(queue.size()> 0)しながら、
実行結果:
コスト時間46422ms
実際の結果に大きな違いは、API ConcurrentLinkedQueueは、不思議そうに遅いコレクションを反復処理するので、サイズの使用を避けるとのisEmptyを使用しようとする元.size()の下に見えました()。
まとめ、特に本番環境では、独自のプログラミングについてのより厳格な要件にテスト対象単位での性能の欠如は、注意する必要があります。
Javaのマルチスレッドアプリケーションでは、キューの使用率が高い、生産および消費モデルの大部分のための選択のデータ構造は、キュー(FIFO)です。スレッドセーフなキューJavaはブロッキングキューBlockingQueueの、非ブロッキングキューの典型的な例の代表例である非ブロッキングブロッキングキューのキューに分けることができる提供してConcurrentLinkedQueue、ブロッキングまたはキューのキューを非ブロッキングに使用する実際の必要に応じて実用的なアプリケーションで。
注意:スレッドセーフとは何ですか?最初に明らか。同じコード、スレッドセーフなマルチスレッドアクセスは、不確定な結果が得られません。
パラレルおよび同時違い
図1は、並列実行が前進二人が保持され、このようなレースのように、両方のことをいう;
2、同時限られたリソースを指し、両方を交互に、道路などのリソースを使用してオン(単コアCPUリソースが)だけで、同時に一人を持っていた、いくつかは、後に行くにB、Bを与えて実行し続け、交換可能に使用さ、それは効率を改善することを目指して
LinkedBlockingQueue
LinkedBlockingQueue実装は生産者と消費者の最初の選択肢であり、FIFO及び他の特性を達成するために、スレッドセーフであるため、LinkedBlockingQueueは、指定された容量であることができるが、指定されていない、指定されていないことができ、デフォルトの最大値は、主に使用されるInteger.MAX_VALUEで、あります置くと方法を取るためにキューが消費されるまで、キューに入れた方法は、フルタイムのメンバーは、ブロックされているキューがメンバーに置かれるまで、空のキューにメソッドのブロックを取ります。
cn.threadパッケージ変更のため、 インポートjava.util.concurrent.BlockingQueue; インポートjava.util.concurrent.ExecutorService; インポートjava.util.concurrent.Executors; インポートjava.util.concurrent.LinkedBlockingQueue; / ** *マルチスレッドのシミュレーションは、生産を達成するために/コンシューマモデル * * @author林チンメーター * @version 1.0 2013年7月25日午後5時23分11秒 * / publicクラスBlockingQueueTest2 { / ** * *定義インストールAppleのバスケット * * / publicクラスバスケット{ 3個のリンゴを収容可能//バスケット ; BlockingQueueの<ストリング>バスケットLinkedBlockingQueue新しい新しい= <文字列>(3) //リンゴ、バスケットに 公共ボイド農産物()は例外:InterruptedExceptionをスロー{ バスケットがいっぱいの場合、位置とバスケットまで待って、リンゴの中にメソッドを置く// basket.put(「アップル」); } //バスケットから削除りんごの消費、 公共の文字列)(消費することはInterruptedExceptionある{スロー //テイクをバスケットは空であるとき、バスケットまでのりんごまで、リンゴを取り出し(キューの先頭を取得および削除) 戻りbasket.take(); } } //メーカーAppleの定義され たクラスを実装したRunnable {プロデューサー プライベートStringインスタンス。 バスケットバスケットプライベート、 パブリックプロデューサ(Stringインスタンス、バスケットバスケット){ this.instance =インスタンス; this.basket =バスケット; } 公共ボイドRUN(){ 試み{ しばらく(真の){ //リンゴ生産 のSystem.out.println( "リンゴを生産する準備ができてプロデューサー:" +インスタンス); basket.produce(); System.out.printlnは(:+インスタンス"リンゴの生産者が、完成生成するために!" ); //スリープ300ミリ秒 のThread.sleep(300); } }キャッチ(InterruptedExceptionあるEX){ するSystem.out.println( "プロデューサー中断"); } } } //アップル消費者定義 クラスの消費者にRunnableを{実装を プライベート文字列インスタンスを; プライベートバスケットバスケット。 一般消費者(Stringインスタンス、バスケットバスケット){ this.instance =インスタンス; this.basket =バスケット; } 公共ボイドRUN(){ 試み{ ながら、(真の){ //消費者のApple のSystem.out.printlnは(「消費者は準備ができていますアップルの消費: "+インスタンス); System.out.printlnは(basket.consumeは()); System.out.printlnは(" Appleは消費者支出を終えた:「+インスタンス);! //睡眠1000ミリ秒 のThread.sleep(1000) ; } }キャッチ(InterruptedExceptionあるEX){ するSystem.out.printlnは( "消費者を中断します")。 } } } パブリック静的な無効メイン(文字列[] args){ BlockingQueueTest2 =新しい新しいBlockingQueueTest2テスト(); //バスケットを作成リンゴ搭載 バスケットバスケットバスケットtest.new =(); ExecutorServiceのExecutors.newCachedThreadPool-SERVICE =()は、 プロデューサープロデューサ= test.newプロデューサ( "プロデューサー001"、バスケット); プロデューサーProducer2 = test.newプロデューサ( "プロデューサー002"、バスケット); 消費者の消費者の消費者test.new =( "消費者001"、バスケット)。 service.submit(プロデューサー); service.submit(Producer2); service.submit(消費者); // 5Sを実行した後、すべてのタスクが停止 {//試してみます //のThread.sleep(* 5 1000)。 //}キャッチ(InterruptedExceptionある電子){ // e.printStackTrace(); //} // service.shutdownNow()。 } }
ConcurrentLinkedQueue
ConcurrentLinkedQueueは、キューのセキュリティの実装です。キューの要素は、FIFO原理によって並べ替えられています。要素の一貫性を確保するために、CAS操作を使用。
LinkedBlockingQueueは、インターフェイスのBlockingQueueを実装スレッドセーフなブロッキングキューで、java.util.Queue BlockingQueueのインターフェイスをブロックするインターフェイスから継承し、メソッドを追加取得し、これらの2つの方法に基づいて、このインタフェースを置くキュー操作でありますバージョン。
cn.threadパッケージ; インポートjava.util.concurrent.ConcurrentLinkedQueue; インポートjava.util.concurrent.CountDownLatch; インポートjava.util.concurrent.ExecutorService; インポートjava.util.concurrent.Executors; publicクラスConcurrentLinkedQueueTest { プライベート静的ConcurrentLinkedQueue <整数> ConcurrentLinkedQueue新しい新しいキュー= <整数>(); //スレッドの数;プライベート静的int型カウント= 2 一つ以上を可能にする操作の集合までたCountDownLatch、同期助剤は、//他のスレッドで実行され、スレッドが待っています。 たCountDownLatch新しい新しいスタティックラッチ=プライベートたCountDownLatch(COUNT); パブリック静的無効メイン(文字列[] args){InterruptedExceptionあるスロー ロングTimeStart =にSystem.currentTimeMillisを(); ES = Executors.newFixedThreadPool ExecutorServiceの(4); ConcurrentLinkedQueueTest.offer(); {(; Iは数<I ++はI = 0の整数)ため es.submit(新しい新しいポーリング()); } latch.await(); //そのlatch.countDown()までメインスレッド(メイン)ブロックは、継続実行前にゼロである ; -のSystem.out.println(TimeStart)+ "MS" "時間コスト" +(のSystem.currentTimeMillis()) ; es.shutdown() } / ** *生産 * / パブリック静的ボイドオファー(){ (INT I = 0; I <100000; I ++の)のために{ Queue.offer(I); } } / ** *消費 * * @authorメートルチンリン * @version 1.0 2013年7月25日午前5時32分56秒下午 * / 静的クラスのポール実装したRunnable { ます。public void実行(){ //しばらく(queue.size()> 0){ しばらく(!queue.isEmpty() ){ System.out.printlnは(queue.poll())。 } latch.countDown()。 } } }
業績:
costtimeの2360ms
スイッチの後(queue.size()> 0)しながら、
実行結果:
コスト時間46422ms
実際の結果に大きな違いは、API ConcurrentLinkedQueueは、不思議そうに遅いコレクションを反復処理するので、サイズの使用を避けるとのisEmptyを使用しようとする元.size()の下に見えました()。
まとめ、特に本番環境では、独自のプログラミングについてのより厳格な要件にテスト対象単位での性能の欠如は、注意する必要があります。