I.はじめに
生産者と消費者は、スレッドモデルの古典的な問題です。プロデューサ/コンシューマの問題を解決する方法は2つあります。まず、生産者と消費者間の同期を保護するメカニズムを使用して、2番目は、生産者と消費者間のパイプラインを確立することです。第1の実施形態は、より高い効率を有し、かつ実装が容易で、より一般的に使用される、より良いコードを、制御することができます。第二パイプは、データ・オブジェクト、バッファを制御することは困難であり、実用性が強くない、等、パッケージに容易に転写されます。
この記事では、プロデューサ/コンシューマの問題を達成するための同期メカニズムの使用を記載しています。
第二に、コード
1、製品の製品カテゴリ:
/ * *产品类
* @author gongyu * * / パブリック クラスの製品{ プライベート int型のID。 プライベート文字列名; 公共製品(int型のID、文字列名){ この .ID = ID。 この .nameの= 名前; } 公共 INT のgetId(){ 戻りID。 } 公共 ボイド SETID(int型のID){ この .ID = ID。 } パブリック文字列のgetName(){ 返す名前を。 } 公共 ボイドのsetName(文字列名){ この .nameの= 名前。 } @Override パブリック文字列のtoString(){ 戻り "商品[ID =" + ID + "NAME =" +名+ "]" 。 } }
2、クラスライブラリの部屋ProductHouse
/ * *図書室クラス * * / パブリック クラスProductHouse { プライベート商品[]製品; プライベート int型の最大値; プライベート int型のインデックス= -1 ; 公共 ProductHouse(int型の最大){ // TODO自動生成コンストラクタスタブ この .MAX = 最大; 製品 = 新新製品[最大]; } / * プロデューサ生成物の保存方法* / 公共 同期 ボイドプッシュ(商品製品){ つつ。(インデックス> = maxの1-){ 試み{ この.WAIT(); } キャッチ(InterruptedExceptionあるE){ // TODO自動生成されたブロックキャッチ e.printStackTrace(); } } この .notifyAll(); //は、他のスレッドウェイク 製品を[++インデックス] = 製品; } / * 消費者は、製品得る* / パブリック 同期商品POP(){ 一方(インデックス<0 ){ 試み{ この.WAITを(); }キャッチ(InterruptedExceptionある電子){ // TODO自動生成キャッチブロック e.printStackTrace(); } } この.notifyAll()。 製品P =製品[index-- ]。 リターンのp; } }
3、プロデューサスレッドProductThread
/ ** *生产者线程ProductThread * @author gongyu * * / パブリック クラス ProductThreadは拡張スレッド{ プライベートProductHouse productHouseを。 公共ProductThread(ProductHouse productHouse、文字列名){ // TODO自動生成されたコンストラクタスタブ スーパー(名); この .productHouse = productHouse。 } 公共 ボイドラン(){ ため(int型 i = 0; iが10 <; iは++ ){ 積P = 新しい製品を第(i + 1、この .getName()+ "馒头" ); System.out.println(この .getName()+ "生产了" + P); productHouse.push(P)。 試す{ のThread.sleep( 500 )。 } キャッチ(InterruptedExceptionある電子){ // TODO自動生成キャッチブロック e.printStackTrace(); } } } }
図4に示すように、消費者スレッドCustomerThread
/ ** *消费者线程CustomerThread * @author gongyu * * / パブリック クラス CustomerThreadは拡張スレッド{ プライベートProductHouse productHouseを。 公共CustomerThread(ProductHouse productHouse、文字列名){ // TODO自動生成されたコンストラクタスタブ スーパー(名); この .productHouse = productHouse。 } 公共 ボイドラン(){ ため(int型、iは5 <; I = 0 iは++ ){ 積P = productHouse.pop()。 System.out.println(この .getName()+ "消费了" + P); } 試みる{ のThread.sleep( 300 )。 } キャッチ(InterruptedExceptionある電子){ // TODO自動生成キャッチブロック e.printStackTrace(); } } }
5、テストクラス
パブリック クラスTEST01 { 公共 静的 ボイドメイン(文字列[]引数){ ProductHouse液pH = 新しい ProductHouse(30 )。 ProductThread P1 = 新しい ProductThread(PH、 "老张" ); ProductThread P2 = 新しい ProductThread(PH、 "老李" ); ProductThread P3 = 新しい ProductThread(PH、 "老杨" ); ProductThread P4 = 新しい ProductThread(PH、 "老王" ); CustomerThread C1 = 新しい CustomerThread(PH、 "小红"); CustomerThread C2 = 新しい CustomerThread(PH、 "小绿" ); CustomerThread C3 = 新しい CustomerThread(PH、 "小蓝" ); CustomerThread C4 = 新しい CustomerThread(PH、 "小白" ); CustomerThread C5 = 新しい CustomerThread(PH、 "小黑" ); CustomerThread C6 = 新しい CustomerThread(PH、 "小灰" ); p1.start(); p2.start(); p3.start(); p4.start()。 c1.start(); c2.start(); c3.start(); c4.start(); c5.start(); c6.start()。 } }