Javaは生産者と消費者モデルを実現する


私は「帆を上げて海に向かう」と書いてあります.このニックネームは私の名前と彼女の名前に由来しています.私は技術が好きで、オープンソースが好きで、プログラミングが好きです. 、 。このブログは自分の勉強の少しの総括と記録で、Java、アルゴリズムに興味があれば、私の動態に注目して、私たちは一緒に勉強します. .
目次
  • 一、生産者及び消費者モデルの説明
  • 二、存在する問題
  • 三、wait()およびnotify()メソッド
  • 4、生産者および消費者モデルに関連するクラス
  • 五、コード実装
  • 一、生産者と消費者モデルの説明
    生産者と消費者の問題はスレッドモデルの古典的な問題である:生産者と消費者は同じ時間帯に同じ記憶空間を共用し、生産者は空間にデータを生産し、消費者は空間からデータを取り出す.
    二、存在する問題
  • 生産者が消費者より速い場合、消費者はデータの一部を漏らす.
  • 消費者が生産者より速い場合、消費者は同じデータを取り出す.

  • 解決方法:スレッドのセキュリティの問題を考慮するには、この問題を解決するには3つの方法があります.
    ①       
    ②       
    ③ lock   ,     Lock  ,  lock()  ,unlock()  ,         
    

    このブログでは、スレッドセキュリティの問題を2つ目の方法で解決しました.
    三、wait()とnotify()の方法wait()nofity()の2つのメソッドにはロックオブジェクト呼び出しが必要であり、任意のオブジェクトはsynchronizedの同期ロックとして使用できるため、この3つのメソッドはObjectクラスでのみ宣言できます.
  • wait():バッファが満/空の場合、生産者または消費者スレッドは自分の実行を停止し、ロックを解放し、自分を待機状態にし、他のスレッドに実行させる.
  • notify():生産者または消費者がバッファに製品を入れたり取り出したりすると、他の待機スレッドに通知を発行し、ロックを解放し、自分を待機状態にし、他のスレッドに実行させる.

  • 四、生産者と消費者モデルに関わる類
  • ショップクラス(Shop):メンバー変数を定義し、いくつかのパンを表し、パンの生産と消費パンの操作を提供する.
  • 生産者クラス(Producer):Runnableインタフェースを実現し、run()メソッドを書き換え、パンの生産操作を呼び出す.
  • 消費者クラス(Consumer):Runnableインタフェースを実現し、run()メソッドを書き換え、消費パンの操作を呼び出す.
  • テストクラス:
  • 五、コード実現
    /**
     *    (Shop):        ,       ,              ;
     */
    class Shop {
        private int bread = 0;
        /**
         *     
         */
        public synchronized void produceBread() {
            if (bread < 10) {
                bread++;
                System.out.println(Thread.currentThread().getName() + ":     " + bread + "   ");
                notify(); //        
            } else {
                try {
                    wait(); //          
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        
        /**
         *     
         */
        public synchronized void consumeBread() {
            if (bread > 0) {
                System.out.println(Thread.currentThread().getName() + ":     " + bread + "   ");
                bread--;
                notify(); //        
            } else {
                try {
                    wait(); //          
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    /**
     *     (Producer):  Thread ,  run()  ,         
     */
    class Producer extends Thread {
        private Shop shop;
    
        public Producer(Shop shop) {
            this.shop = shop;
        }
    
        @Override
        public void run() {
            System.out.println(getName() + ":      .....");
            while (true) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                shop.produceBread();
            }
        }
    }
    
    /**
     *     (Consumer):  Thread ,  run()  ,         
     */
    class Consumer extends Thread {
        private Shop shop;
        public Consumer(Shop shop) {
            this.shop = shop;
        }
        
        @Override
        public void run() {
            System.out.println(getName() + ":      .....");
            while (true) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                shop.consumeBread();
            }
        }
    }
    
    public class BreadTest {
        public static void main(String[] args) {
            //       
            Shop shop = new Shop();
            //        ,                     
            Producer p1 = new Producer(shop);
            p1.setName("   ");
            //        ,                     
            Consumer c1 = new Consumer(shop);
            c1.setName("   ");
    
            p1.start();
            c1.start();
            
        }
    }
    

    コードの実行結果は次のとおりです.
       :      .....
       :      .....
       :     1   
       :     2   
       :     3   
       :     4   
       :     4   
       :     4   
       :     5   
       :     6   
       :     7   
       :     8   
       :     8   
       :     8   
       :     9   
       :     10   
       :     10   
       :     10   
       :     10   
       :     10   
       :     10   
       :     10   
       :     10   
    
    ...
    
    

    前回のマルチスレッド(一)スレッドの紹介と作成
    次のマルチスレッド(3)マルチスレッドは複数のウィンドウの切符販売問題を実現する