プロデューサーと消費者モデルを実装するいくつかの方法
例として私たちの生活の模範を見てください。工場で生産される製品は、常に屋外で使用するために輸出されています。これが生産と消費の概念です。
実際のソフトウェア開発プロセスでは、多くの場合、次のシナリオが発生します。モジュールはデータの生成に責任があり、このデータは別のモジュールによって処理されます(ここのモジュールは一般化されています。これはクラス、関数、スレッド、プロセスなどです)。
データを生成するモジュールは、プロデューサーと鮮やかに呼ばれます。一方、データを処理するモジュールは消費者と呼ばれます。
最初のタイプ:Wait-Notifyを使用して、プロデューサーと消費者モデルを実装する
1。プロデューサーと消費者:
2。1つの生産者と複数の消費者:
2番目のタイプ:ブロッキングキューを使用してプロデューサーと消費者モデルを実装する
3.ブロッキングキューを使用して、プロデューサー - 消費者パターンを実装します
誰もが日本料理に行ったと思います。バーベキューである非常に魅力的な食事があります。バーベキューマスターは横に立ってバーベキューを続け、ローストした肉を皿の上に置きます。よだれを垂らしている私たちは横に座っているので、皿に肉がある限り食べ続けます。
このライフの場合、バーベキューマスターはプロデューサーであり、バーベキューの責任者です。焙煎後、彼は肉をダイナーに直接渡すのではなく、プレートに肉を置きます(つまり、肉を食べるためにダイナーに通知する必要はありません)。プレートの肉がいっぱいの場合、マスターは肉を生産する前に誰かがバーベキューを食べに行くまでしばらく止まります。そして、食事は皿を見つめているだけで、プレートに肉があると、私たちはそれを食べる責任があります。
プロセス全体で、ダイナーとバーベキューマスターはお互いに直接対処しませんでしたが、プレートと対話しました。
プレートはバッファーの概念として機能します。何かが生成されている場合は、それを入れてください。プレートにはサイズの制限もあります。プレートのサイズを超えた場合、生産者の生産をブロックし、消費者が消費するのを待ちます。プレートが空になると、消費者の消費をブロックし、生産者が生産するのを待ちます。
プログラミング中にキューをブロックすると、ディスクの機能が実現できます。
ブロッキングキューの特性:
キュー要素がいっぱいになったら、挿入操作をブロックします。
キュー要素が空の場合、取得操作がブロックされます。
ArrayBlockingQueueとLinkedBlockingQueueの両方がFIFO(最初は、最初に)をサポートしていますが、LinkedBlockingQueueはバウンドされていませんが、ArrayBlockingQueueはバウンドされています。
以下は、ブロッキングキューを使用して生産者と消費者を実装します。
プロデューサー:
java.util.concurrent.blockingqueue;パブリッククラスプロデューサーは実行可能{プライベートファイナルブロッキングクロッキングブロッキングキュー; //キューキャッシュのサイズを設定します。生産プロセス中にこのサイズを超えた後、生産は一時的に停止します。プライベートファイナルint queue_size = 10; public producer(blockingqueue blockingqueue){this.blockingqueue = blockingqueue;} int task = 1; @override public void run(){while(true){try {system.out.println( "生産:"+タスク);エフェクトスレッドの表示を容易にするために、スリープ(1000);} catch(arternedexception e){e.printstacktrace();}}}}}消費者:
java.util.concurrent.blockingqueue; //消費者パブリッククラスの消費者はrunnable {private final blockingqueue blockingqueue; public blockingqueue){this.blockingqueue;}@blocking bockqueue;}@override public void run(){// {system.out.println( "Consuming:" + BlockingQueue.Take()); //しばらくの間停止して、Effect Thread.Sleep(2000);} catch(arternedexception e){e.printstacktrace();}}}}}}テスト:
java.util.concurrent.blockingqueue;インポートJava.util.concurrent.linkedblockingQueue;/** *プロデューサー消費者モード *ブロッキングキューブロッキングQueue * @author wanggenshen * * */public class testconpro {public static bockingeue = arges ogsed blockqueedblockqueed blockqueed blockqueue blockqueue blocked blockqueue( p = new Producer(blockingQueue); Consumer C = new Consumer(BlockingQueue);スレッドTP = newスレッド(P);スレッドTC = newスレッド(c); tp.start(); tc.start();}}}LinkedBlockingQueueは無制限のキューであるため、プロデューサーは引き続き生産され、生産されたタスクをキューに入れ、消費者はキューで消費します。
代わりに、境界ブロッキングキューアレイブロッキングキューを使用する場合、キューサイズを初期化できます。次に、キュー内の要素がキューサイズを超えると、プロデューサーは消費者が一方を消費するのを待ち、次のものを生産します。
テストコード:
サイズ10のarrayblockingQueueを初期化:
public static void main(string [] args){blockingqueue blockingqueue(10);プロデューサーp = newプロデューサー(blockingqueue);消費者c = new Consumer(blockingqueue); swreet(blockingqueue); swreet(p); swreet tc = newスレッド(c); tp.start(); tc.start(); tc.start(); tc.start();テスト中、生産者は少し速く生産することが許可されましたが、消費者は遅くなりました。生成された製品シリアル番号と消費される製品シリアル番号の違いは、常に10(キューのサイズ)であることがわかります。
要約します
上記は、生産消費者モデルの実装方法とスレッドの安全性の問題のコード例に関するこの記事の内容全体です。私はそれが誰にでも役立つことを願っています。興味のある友人は、このサイトの他の関連トピックを引き続き参照できます。欠点がある場合は、それを指摘するためにメッセージを残してください。このサイトへのご支援をありがとうございました!