【全棧之路】JAVA基礎課程四_生產者消費者問題(20190614v1.1)

歡迎進入JAVA基礎課程

博客地址:https://blog.csdn.net/houjiyu...
本系列文章將主要針對JAVA一些基礎知識點進行講解,爲平時概括所總結,無論是剛接觸JAVA開發菜鳥仍是業界資深人士,都但願對廣大同行帶來一些幫助。如有問題請及時留言或加QQ:243042162。多線程

寄語:*
「天眼」之父南仁東,心無旁騖,爲崇山峻嶺間的中國「天眼」燃盡生命,看似一口「大鍋」,天眼是世界上最大、最靈敏的單口徑射電望遠鏡,能夠接受百億光年外的電磁信號。南仁東總工程師執着追求科學夢想的精神,將激勵一代又一代科技工做者繼續奮鬥,勇攀世界科技高峯。做爲IT界的從業者,咱們須要緊跟時代的步伐,踏過平庸,一輩子爲科技築夢。

生產者消費者問題

1. 背景 ide

生產者消費者問題(Producer-consumer problem),也稱有限緩衝問題(Bounded-buffer problem),是一個多線程同步問題的經典案例。生產者生成必定量的數據放到緩衝區中,而後重複此過程;與此同時,消費者也在緩衝區消耗這些數據。生產者和消費者之間必須保持同步,要保證生產者不會在緩衝區滿時放入數據,消費者也不會在緩衝區空時消耗數據。不夠完善的解決方法容易出現死鎖的狀況,此時進程都在等待喚醒。.net

2. 條件線程

  • 生產者僅僅在倉儲未滿時候生產, 倉滿則中止生產.
  • 生產者在生產出可消費產品時候, 應該通知等待的消費者去消費.
  • 消費者僅僅在倉儲有產品時候才能消費, 倉空則等待.
  • 消費者發現倉儲沒產品可消費時候會通知生產者生產.

3.實現方式code

  • wait() / notify()方法
  • await() / signal()方法
  • BlockingQueue阻塞隊列方法
  • Semaphore方法
  • PipedInputStream / PipedOutputStream

下面主要針對前面三種方式作代碼實現blog

(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()方法ip

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<Integer> bq = new ArrayBlockingQueue<Integer>(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
相關文章
相關標籤/搜索