併發:阻塞隊列與生產者消費者模型

  對於生產者消費者模型,如果我們採用常規的容器,那麼我們需要同步,並且需要在生產者線程和消費者線程之間做wait和notify的線程間通信。而阻塞隊列將同步操作和生產者和消費者間的通信在容器內部實現,使用起來就不需要我們自己做同步和線程通信了。
  Java中提供的BlockingQueue包括:
  ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue。
  一個典型的應用場景就是socket客戶端數據的讀取和解析。

另外關於生產者-消費者模型,下面是採用Object.wait(),Object.notify()非阻塞容器實現的生產者-消費者模式:
摘抄自此

public class Test {
    private int queueSize = 10;
    private PriorityQueue<Integer> queue = new PriorityQueue<Integer>(queueSize);

    public static void main(String[] args)  {
        Test test = new Test();
        Producer producer = test.new Producer();
        Consumer consumer = test.new Consumer();

        producer.start();
        consumer.start();
    }

    class Consumer extends Thread{

        @Override
        public void run() {
            consume();
        }

        private void consume() {
            while(true){
                synchronized (queue) {
                    while(queue.size() == 0){
                        try {
                            System.out.println("隊列空,等待數據");
                            queue.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                            queue.notify();
                        }
                    }
                    queue.poll();          //每次移走隊首元素
                    queue.notify();
                    System.out.println("從隊列取走一個元素,隊列剩餘"+queue.size()+"個元素");
                }
            }
        }
    }

    class Producer extends Thread{

        @Override
        public void run() {
            produce();
        }

        private void produce() {
            while(true){
                synchronized (queue) {
                    while(queue.size() == queueSize){
                        try {
                            System.out.println("隊列滿,等待有空餘空間");
                            queue.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                            queue.notify();
                        }
                    }
                    queue.offer(1);        //每次插入一個元素
                    queue.notify();
                    System.out.println("向隊列取中插入一個元素,隊列剩餘空間:"+(queueSize-queue.size()));
                }
            }
        }
    }
}
發佈了59 篇原創文章 · 獲贊 9 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章