作業系統·Java實現阻塞隊列的設計 (本質上是Java實現生產者消費者問題)·Condition條件變數

  • 2020 年 2 月 18 日
  • 筆記

如果寫得好或對您有幫助,麻煩右邊點下贊哈~~~這樣能幫助到更多的人。

訊號量主要關注進程間通訊;條件變數、互斥鎖(如Java中的讀寫鎖Rerentlock(可能有誤))主要關注執行緒間通訊,條件變數總和互斥鎖一起使用。

生產者消費者問題的描述:請自行百度。

  • 緩衝區 是 臨界區,同一時刻只能允許一個生產者put或一個消費者get。
  • 生產環境中應當是非阻塞隊列效率更高,一邊消費的同時可以一邊生產。

Java實現阻塞隊列的幾種方式

  • 一、採用synchronized鎖以及wait notify方法實現
  • 二、採用Lock鎖以及await(P)和signal(V)方法實現
    • 使用BlockingQueue可進一步簡化程式碼,不需要編寫執行緒同步資源和喚醒執行緒的程式碼。
    • 可以先參考我的有道雲的執行緒同步
  • 三、採用BlockingQueue實現
    • 源碼使用重入鎖、條件變數來實現。
    • 阻塞隊列的使用例子. http://blog.csdn.net/feichenwangyalin/article/details/50913265
    • BlockingQueue也是java.util.concurrent下的主要用來控制執行緒同步的工具。
    • BlockingQueue有四個具體的實現類,根據不同需求,選擇不同的實現類
      • 1、ArrayBlockingQueue: 大小固定;其所含的對象是以FIFO(先入先出)順序排序的。
      • 2、LinkedBlockingQueue:大小不定.其所含的對象是以FIFO(先入先出)順序排序的。
      • 3、PriorityBlockingQueue:類似於LinkedBlockQueue,但其所含對象的排序不是FIFO,而是依據對象的自然排序順序或者是構造函數的Comparator決定的順序。
      • 4、SynchronousQueue:特殊的BlockingQueue,對其的操作必須是放和取交替完成的。

互斥鎖Rerentlock加條件變數實現BlockQueue

import java.util.LinkedList;  import java.util.concurrent.locks.Condition;  import java.util.concurrent.locks.Lock;  import java.util.concurrent.locks.ReentrantLock;      public class LinkedBlockingQueue<E> {      private final int capacity;        private Lock lock = new ReentrantLock();      private LinkedList<E> queue;//緩衝區      private int count; //緩衝區商品個數      private Condition unfull = lock.newCondition();      private Condition unEmpty = lock.newCondition();        public LinkedBlockingQueue() throws InterruptedException {          this(Integer.MAX_VALUE);      }          public LinkedBlockingQueue(int capacity) throws InterruptedException {          this.capacity = capacity;          queue = new LinkedList<E>();      }          public void put(E e) throws InterruptedException {            try {              while (count == capacity) {                  unfull.await();//阻塞隊列已滿,一直等待,直到有unfull              }              lock.lock(); //內層互斥夾緊              queue.add(e);              count++;              lock.unlock();              unfull.signal();          } finally {            }      }        public E take() throws InterruptedException {            try {              while (count == 0) {//隊列為空,阻塞.一直等待指導有商品(unEmpty)                  unEmpty.await();              }              lock.lock();              E e = queue.pop();              count--;              lock.unlock();              unEmpty.signal();              return e;          } finally {            }      }    }

Java 多執行緒(五)- 理解 Condition 和 條件變數. https://www.jianshu.com/p/82bdd60ff816

Tags: