1。コンセプト
生産者と消費者の問題は、ジンディアンのマルチスレッドコラボレーションの問題です。生産者は、製品を生産し、倉庫に保管する責任があります。消費者は倉庫から製品を入手して消費します。倉庫がいっぱいになったら、生産者は製品が保管される場所があるまで生産を停止する必要があります。倉庫が空の場合、消費者は倉庫に製品が存在するまで消費を停止する必要があります。
次の手法は、主に生産者/消費者の問題を解決するために使用されます。1。スレッドを使用して生産者をシミュレートし、実行方法の倉庫に製品を継続的に保存します。 2。スレッドを使用して消費者をシミュレートし、実行方法で倉庫から製品を継続的に取得します。 3
。倉庫クラスは製品を保存します。製品の数が0の場合、待機方法が呼び出され、現在の消費者スレッドが待機状態に入ります。新しい製品が保存されると、Notifyメソッドが呼び出され、待機中の消費者スレッドが目覚めます。倉庫がいっぱいになると、待機方法が呼び出され、現在の生産者スレッドが待機状態に入ります。消費者が製品を取得すると、Notifyメソッドが呼び出され、待機中のプロデューサースレッドを覚ます。
2。例
パッケージbook.thread.product;パブリッククラスの消費者はスレッドを拡張します{プライベートウェアハウスウェアハウス; //消費者が製品を取得する倉庫= false; // end swrepのフラグビットは、必要なパブリック消費者(倉庫倉庫、文字列名){super(name); this.warehouse = warehouse; } public void start(){this.running = true; super.start(); } public void run(){Product Product; try {while(running){//倉庫から製品を取得= warehouse.getProduct();睡眠(500); }} catch(arturnedexception e){e.printstacktrace(); }} //消費者スレッドを停止しますpublic void stopconsumer(){synchronized(warehouse){this.running = false; warehouse.notifyall(); //倉庫を待っているスレッドを通知}} //消費者スレッドがpublic boolean isrunning(){return running; }} package book.thread.product;パブリッククラスプロデューサーはスレッド{プライベートウェアハウスウェアハウス; //製品の倉庫を保存するプライベート静的int生産= 0; //製品の名前プライベートブールランニング= false; this.warehouse = warehouse; } public void start(){this.running = true; super.start(); } public void run(){Product Product; //製品を生産して保存してくださいtry {while(running){product = new Product((++ ProductName)+""); this.warehouse.storageproduct(croduct);睡眠(300); }} catch(arturnedexception e){e.printstacktrace(); }} //プロデューサースレッドを停止しますpublic void stopproducer(){synchronized(warehouse){this.running = false; //倉庫倉庫倉庫倉庫を待っているスレッドに通知します。NotifyAll(); }} //プロデューサースレッドがpublic boolean isrunning(){return running; }} package book.thread.product; public class product {private string name; // product name public product(string name){this.name = name; } public string toString(){return "doct-"+name; }} package book.thread.product; //製品の倉庫クラスは配列を使用して製品のパブリッククラス倉庫を保存するために配列キューを表します{プライベート静的int容量= 11; Warehouse Private int Rear = 0; // Warehouseの最後の未装備製品の添え字に1パブリックウェアハウス(){this.products = new製品[容量]; } public warehouse(int capacity){this(); if(容量> 0){容量=容量+1; this.products =新製品[容量]; } } //Get a product from the warehouse public Product getProduct() throws InterruptedException{ synchronized(this){ boolean consumerRunning = true;//Tag whether the consumer thread is still running Thread currentThread = Thread.currentThread();//Get the current thread if(currentThread instance of Consumer){ consumerRunning = ((Consumer)currentThread).isRunning(); } else {return null; //消費者は製品を取得できません} //消費者スレッドが実行されているが、倉庫に製品がない場合、消費者スレッドは(フロント==リア)&&消費){wait(); consumerrunning =((消費者)currentThread).isrunning(); } //消費者スレッドが実行を停止した場合、メソッドを終了して製品をキャンセルする場合(!consonerrunning){return null; } //現在製品=製品[フロント]を消費していない最初の製品を取得します。 System.out.println( "Consumer ["+currentThread.getName()+"] getProduct:"+crodce); //現在消費されていない製品の添え字を1つずつ移動させます。配列の端に達した場合、ヘッダーフロント=(フロント+1+容量)%容量に移動します。 System.out.println( "倉庫でまだ消費されていない製品の量:"+(後部+容量 - フロント)%容量); //他の待機スレッドに通知notify();返品製品。 }} //製品を倉庫にストレージパブリックvoid storeproduct(製品製品)が割り込みexceptionをスローします{synchronized(this){boolean producererrunning = true; //プロデューサースレッドがスレッドcurrentthread = thread.currentthread() if(currentthread instance of producer){producererunning =((producer)currentthread).isrunning(); } else {return; } //最後の消費されていない製品が最初の未装備製品の添え字の隣にある場合、それはストレージスペースがないことを意味します。 //ストレージスペースがなく、プロデューサースレッドがまだ実行されている場合、プロデューサースレッドは倉庫が製品をリリースするのを待ちます(((後部+1)%容量==フロント)&& producererunning){wait(); producererunning =((producer)currentthread).isrunning(); } //生産スレッドの実行が停止した場合、(!producerrunning){return; } //製品を倉庫製品に保存[Lear] =製品; system.out.println( "producer [" + thread.currentthread()。getName() + "] storageproduct:" + product); //次々とサブスクリプトを変更します。リア=(リア + 1)%容量。 System.out.println( "倉庫で消費されていない製品の量:" +(後部 +容量)%容量); notify(); }}} package book.thread.product; public class testproduct {public static void main(string [] args){warehouse warehouse = new Warehouse(10); // 10の容量を持つ倉庫を作成しますプロデューサープロデューサー2 =新しいプロデューサー(Warehouse、 "Producer-2");プロデューサープロデューサー3 =新しいプロデューサー(Warehouse、 "Producer-3"); Consumer Consumer1 = new Consumer(Warehouse、 "Consumer-1"); Consumer Consumer2 = new Consumer(Warehouse、 "Consumer-2"); Consumer Consumer3 = New Consumer(Warehouse、 "Consumer-3"); Consumer Consumer4 = new Consumer(Warehouse、 "Consumer-4"); //プロデューサースレッドを起動すると、消費者スレッドは1.start()を生成します。生産者2.start(); Consumer1.start(); producers3.start(); Consumer2.start(); Consumer3.start(); Consumer4.start(); // 1600msのプロデューサー/コンシューマープログラムを実行させてください{thread.sleep(1600); } catch(arturnedexception e){e.printstacktrace(); } //消費者スレッドを停止します1.StopProducer(); Consumer1.StopConsumer();生成者2.StopProducer(); Consumer2.StopConsumer(); producers3.StopProducer(); Consumer3.StopConsumer(); Consumer4.StopConsumer(); }}出力結果:
生産者[生産者-1]ストレージ製品:製品1倉庫で消費されていない製品の数:1COSSUMER [Consumer-2] GetProduct:Product-1 Warehouseで消費されていない製品の数:0プロデューサー[生産者-3] StorageProduct:Product-3 Warehouseで消費されていない製品の数Product-2倉庫で消費されていません:2Consumer [Consumer-3] GetProduct:Product-3 Warehouseで消費されていない製品の数:1COSSUMER [Consumer-1] GetProduct:Product-2 Warehouseで消費されていない製品の数:0プロダューサー1] 1COSUMER [Consumer-4] GetProduct:Product-4 Warehouseで消費されていない製品の数:0Producer [Producter-3] StorageProduct:Product-6 Warehouseで消費されていない製品の数:1Producer [Producter-2] StorageProduct:Product-5 warehouseで消費されていない製品の数GetProduct:製品で消費されていない製品の数-6倉庫:1COSSUMER [Consumer-2] GetProduct:Product-5倉庫で消費されていない製品の数:0プロデューサー[生産物]ストレージプロダクト:製品の数を摂取していない製品の数:消費者[消費者]を使用する製品の数: Product-7倉庫:0プロデューサー[生成物3]ストレージプロダクト:Product-8倉庫で消費されていない製品の数:1Producer [生産者2]ストレージプロダクト:倉庫で消費されていない製品の数:2 Consumer [Consumer-4] GetProduct:get-8 of that ware in that of of the ware 1プロデューサー[生成物]ストレージプロダクト:倉庫で消費されていない製品の数:2プロデューサー[生産者]ストレージプロダクト:倉庫で消費されていない製品の数:3プロデューサー[プロデュース-2]ストレージプロダクト:製品の消費者:4cosumer:get-consumer倉庫で消費されていない製品の数:3Consumer [Consumer-2] GetProduct:倉庫で消費されていない製品の数:2Consumer [Consumer-3] GetProduct:製品-11倉庫で消費されていない製品の数:1プロデューサー[生産者]貯蔵:製品2プロデューサー[生産者]ストレージプロダクト:製品14倉庫で消費されていない製品の数:3プロデューサー[生産者2]ストレージプロダクト:倉庫で消費されていない製品の数:4Cossumer [Consumer-4] GetProduct:Product-1uct-conduct:get-1uctumer:3cosupersumersumersumer倉庫で消費されていない製品の数:2Consumer [Consumer-2] GetProduct:製品-14倉庫で消費されていない製品の数:1プロデューサー[生産者]ストレージプロダクト:製品-16倉庫で消費されていない製品の数:2プロデューサー[生産者-3] 3Producer [Producttr-2] StorageProduct:Product-18倉庫で消費されていない製品の数:4
分析:製品倉庫はメイン方法で確立されており、倉庫は3つのプロデューサースレッドと4つの消費者スレッドを関連付けていません。これらのスレッドは、プロデューサー/消費者モデルを機能させるために開始されます。プログラムが1600ミリ秒間実行されると、すべての生産者が製品の生産を停止し、消費者は製品の消費を停止します。
プロデューサースレッド製品は、実行方法に300msのない製品を生産し、倉庫に保存します。消費者スレッドの消費者は、実行方法が500msなしで倉庫から製品を取得します。
倉庫は、製品の保管と配布を担当しています。 StorageProductメソッドは、製品の保存を担当します。倉庫がいっぱいになると、現在のスレッドが待機状態に入ります。つまり、プロデューサースレッドAがストレージ製品を呼び出して製品を保存すると、倉庫がいっぱいで保存できないことがわかります。ストレージ製品が成功した場合、Notifyメソッドが呼び出され、待機中の消費者スレッドが目覚めます。
GetProductメソッドは、事前に製品を担当します。倉庫が空の場合、現在のスレッドは待機状態になります。つまり、消費者スレッドBがGetProductメソッドを呼び出して製品を取得すると、倉庫が空であることがわかり、待機状態になります。製品が正常に抽出された場合、Notifyメソッドが呼び出され、待機中のプロデューサースレッドを目覚めさせます。
上記の記事では、Javaスレッドの生産者と消費者の問題について簡単に説明します。私があなたと共有するすべてのコンテンツです。私はそれがあなたに参照を与えることができることを願っています、そしてあなたがwulin.comをもっとサポートできることを願っています。