【全桟の道】JAVA基礎コース4_生産者消費者問題(20190614 v 1.1)


JAVA基礎コースへようこそ
ブログアドレス:https://segmentfault.com/a/11...このシリーズの文章は主にJAVAのいくつかの基礎知識点について説明し、普段のまとめのためにまとめ、JAVAの開発菜鳥に接触したばかりであれ、業界のベテランであれ、多くの同業者に助けを与えたいと思っています.問題があれば、すぐに伝言を残したり、QQ:243042162を追加したりしてください.
メッセージ:
「天眼」の父南仁東は、崇山と険しい嶺の間の中国の「天眼」のために命を捧げた.南仁東総技師は科学の夢を追求する精神に執着し、一代また一代の科学技術従事者が引き続き奮闘し、世界の科学技術のピークに勇敢に登ることを激励する.IT業界の従事者として、私たちは時代の歩みに追いつき、平凡を踏んで、一生科学技術のために夢を築く必要があります.
生産者消費者問題
1.背景
生産者消費者問題(Producer-consumer problem)は、有限バッファ問題(Bounded-buffer problem)とも呼ばれ、マルチスレッド同期問題の古典的な例である.生産者は一定量のデータをバッファに生成し、このプロセスを繰り返します.同時に、消費者もバッファでこれらのデータを消費します.生産者と消費者の間で同期を保たなければならない.生産者がバッファがいっぱいになったときにデータを入れないことを保証し、消費者もバッファが空いているときにデータを消費しないことを保証しなければならない.不十分な解決策では、デッドロックが発生しやすく、プロセスが起動を待っています.
2.条件
  • 生産者は倉庫が満たせない時だけ生産し、倉庫が満たせば生産を停止する.
  • .
  • 生産者は、消費可能な製品を生産する際に、待機する消費者に消費を通知すべきである.
  • 消費者は製品が倉庫に保管されているときだけ消費することができ、倉庫の空きは待つ.
  • 消費者は倉庫に製品が消費できないことを発見した場合、生産者に生産を通知する.
  • 3.実現方式
  • wait()/notify()メソッド
  • await()/signal()メソッド
  • BlockingQueueブロッキングキューメソッド
  • Semaphoreメソッド
  • PipedInputStream/PipedOutputStream

  • 以下は主に前の3つの方式に対してコードの実現をします
    (1)wait()/notify()メソッド
    public class ProducerMain {
    
        private static Integer count=0;
        private final Integer full=10;
        private static String LOCK="LOCK";
    
        class  Producer implements Runnable{
    
            @Override
            public void run() {
    //            for(int i=0;i<10;i++){
    //                try {
    //                    Thread.sleep(3000);
    //                } catch (InterruptedException e) {
    //                    e.printStackTrace();
    //                }
    //            }
                synchronized (LOCK){
                    while(count==full){
                        try {
                            LOCK.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
    
                    }
                    count++;
                    System.out.println(Thread.currentThread().getName()+"     ,      :"+count);
                    LOCK.notifyAll();
                }
            }
        }
        class Consumer implements Runnable{
    
            @Override
            public void run() {
                synchronized (LOCK){
                    while (count==0){
                        try {
                            LOCK.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    count--;
                    System.out.println(Thread.currentThread().getName()+"     ,     :"+count);
                    LOCK.notifyAll();
                }
            }
        }
    
        public static void main(String[] args) {
            ProducerMain producer = new ProducerMain();
            new Thread(producer.new Producer()).start();
            new Thread(producer.new Consumer()).start();
            new Thread(producer.new Producer()).start();
            new Thread(producer.new Consumer()).start();
            new Thread(producer.new Producer()).start();
            new Thread(producer.new Consumer()).start();
            new Thread(producer.new Producer()).start();
            new Thread(producer.new Consumer()).start();
        }
    }

    出力結果
    Thread-0     ,      :1
    Thread-5     ,     :0
    Thread-2     ,      :1
    Thread-7     ,     :0
    Thread-6     ,      :1
    Thread-1     ,     :0
    Thread-4     ,      :1
    Thread-3     ,     :0
    

    (2)await()/signal()メソッド
    public class ReentrantLockDemo {
        private static Integer count = 0;
        private final Integer FULL = 10;
        final Lock lock = new ReentrantLock();
        final Condition NotFull = lock.newCondition();
        final Condition NotEmpty = lock.newCondition();
    
        class Producer implements Runnable {
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    try {
                        Thread.sleep(3000);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    lock.lock();
                    try {
                        while (count == FULL) {
                            try {
                                NotFull.await();
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }
                        count++;
                        System.out.println(Thread.currentThread().getName()
                                + "     ,     " + count);
                        NotEmpty.signal();
                    } finally {
                        lock.unlock();
                    }
    
                }
            }
        }
    
        class Consumer implements Runnable {
    
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e1) {
                        e1.printStackTrace();
                    }
                    lock.lock();
                    try {
                        while (count == 0) {
                            try {
                                NotEmpty.await();
                            } catch (Exception e) {
                                // TODO: handle exception
                                e.printStackTrace();
                            }
                        }
                        count--;
                        System.out.println(Thread.currentThread().getName()
                                + "     ,     " + count);
                        NotFull.signal();
                    } finally {
                        lock.unlock();
                    }
    
                }
    
            }
    
        }
    
        public static void main(String[] args) throws Exception {
            ReentrantLockDemo hosee = new ReentrantLockDemo();
            new Thread(hosee.new Producer()).start();
            new Thread(hosee.new Consumer()).start();
            new Thread(hosee.new Producer()).start();
            new Thread(hosee.new Consumer()).start();
    
            new Thread(hosee.new Producer()).start();
            new Thread(hosee.new Consumer()).start();
            new Thread(hosee.new Producer()).start();
            new Thread(hosee.new Consumer()).start();
        }
    }
    

    出力結果
    Thread-0     ,     1
    Thread-2     ,     2
    Thread-1     ,     1
    Thread-7     ,     0
    Thread-6     ,     1
    Thread-5     ,     0
    Thread-4     ,     1
    Thread-3     ,     0
    Thread-0     ,     1
    Thread-2     ,     2
    Thread-1     ,     1
    Thread-6     ,     2
    Thread-7     ,     1
    Thread-5     ,     0
    Thread-4     ,     1
    Thread-3     ,     0
    Thread-0     ,     1
    Thread-2     ,     2
    Thread-1     ,     1
    Thread-7     ,     0
    Thread-6     ,     1
    Thread-5     ,     0
    Thread-4     ,     1
    Thread-3     ,     0
    Thread-0     ,     1
    Thread-2     ,     2
    Thread-1     ,     1
    Thread-7     ,     0
    Thread-6     ,     1
    Thread-5     ,     0
    Thread-4     ,     1
    Thread-3     ,     0
    Thread-0     ,     1
    Thread-2     ,     2
    Thread-1     ,     1
    Thread-6     ,     2
    Thread-7     ,     1
    Thread-5     ,     0
    Thread-4     ,     1
    Thread-3     ,     0
    Thread-2     ,     1
    Thread-0     ,     2
    Thread-1     ,     1
    Thread-7     ,     0
    Thread-6     ,     1
    Thread-5     ,     0
    Thread-4     ,     1
    Thread-3     ,     0
    Thread-2     ,     1
    Thread-0     ,     2
    Thread-1     ,     1
    Thread-6     ,     2
    Thread-7     ,     1
    Thread-5     ,     0
    Thread-4     ,     1
    Thread-3     ,     0
    Thread-2     ,     1
    Thread-0     ,     2
    Thread-1     ,     1
    Thread-6     ,     2
    Thread-7     ,     1
    Thread-5     ,     0
    Thread-4     ,     1
    Thread-3     ,     0
    Thread-2     ,     1
    Thread-0     ,     2
    Thread-1     ,     1
    Thread-6     ,     2
    Thread-7     ,     1
    Thread-4     ,     2
    Thread-5     ,     1
    Thread-3     ,     0
    Thread-0     ,     1
    Thread-2     ,     2
    Thread-1     ,     1
    Thread-6     ,     2
    Thread-7     ,     1
    Thread-5     ,     0
    Thread-4     ,     1
    Thread-3     ,     0
    
    

    (3)BlockingQueueブロックキューメソッド
    public class BlockingQueueMain {
        private static Integer count = 0;
        final BlockingQueue bq = new ArrayBlockingQueue(10);
        class Producer implements Runnable {
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    try {
                        Thread.sleep(3000);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    try {
                        bq.put(1);
                        count++;
                        System.out.println(Thread.currentThread().getName()
                                + "     ,     " + count);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    
        class Consumer implements Runnable {
    
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e1) {
                        e1.printStackTrace();
                    }
                    try {
                        bq.take();
                        count--;
                        System.out.println(Thread.currentThread().getName()
                                + "     ,     " + count);
                    } catch (Exception e) {
                        // TODO: handle exception
                        e.printStackTrace();
                    }
                }
            }
    
        }
    
        public static void main(String[] args) throws Exception {
            BlockingQueueMain hosee = new BlockingQueueMain();
            new Thread(hosee.new Producer()).start();
            new Thread(hosee.new Consumer()).start();
            new Thread(hosee.new Producer()).start();
            new Thread(hosee.new Consumer()).start();
    
            new Thread(hosee.new Producer()).start();
            new Thread(hosee.new Consumer()).start();
            new Thread(hosee.new Producer()).start();
            new Thread(hosee.new Consumer()).start();
        }
    }
    

    出力結果
    Thread-1     ,     0
    Thread-4     ,     1
    Thread-0     ,     0
    Thread-5     ,     0
    Thread-3     ,     0
    Thread-2     ,     1
    Thread-6     ,     1
    Thread-7     ,     0
    Thread-4     ,     1
    Thread-1     ,     0
    Thread-0     ,     1
    Thread-5     ,     0
    Thread-2     ,     1
    Thread-3     ,     0
    Thread-6     ,     0
    Thread-7     ,     0
    Thread-4     ,     0
    Thread-1     ,     0
    Thread-0     ,     1
    Thread-5     ,     0
    Thread-2     ,     1
    Thread-3     ,     0
    Thread-6     ,     1
    Thread-7     ,     0
    Thread-4     ,     1
    Thread-1     ,     0
    Thread-0     ,     1
    Thread-5     ,     0
    Thread-2     ,     1
    Thread-3     ,     0
    Thread-6     ,     1
    Thread-7     ,     0
    Thread-4     ,     2
    Thread-0     ,     1
    Thread-1     ,     0
    Thread-5     ,     1
    Thread-2     ,     1
    Thread-3     ,     0
    Thread-6     ,     1
    Thread-7     ,     0