JavaWeb~實現生產者消費者模型(BlockingQueue阻塞隊列)

如何實現生產者消費者模型?

  • 簡單來說就是使用阻塞隊列來實現該模型
  • 阻塞隊列的實現:
  1. 阻塞隊列依舊是一個先進先出的隊列
  2. 入隊列時如果發現隊列滿了,就會阻塞,直到其他線程調用出隊列操讓隊列有空位之後 ,才能繼續入隊列
  3. 出隊列的時候如果發現隊列爲空,也會阻塞, 直到其他線程調用入隊列操作rag隊列有元素,才能繼續出隊列

實現阻塞隊列

//阻塞隊列

public class BlockingQueue {

    private int[] array = new int[20];
    private int haed = 0;
    private int tail = 0;
    private volatile int size = 0;

    //put向隊列放元素
    public void put(int val) throws InterruptedException {

        synchronized (this) {

            while (this.size == array.length) {
                this.wait();
            }

            array[tail] = val;
            tail++;
            size++;
            if (tail == array.length) {
                this.tail = 0;
            }

            this.notify();
        }
    }

    //take取隊首元素
    public int take() throws InterruptedException {

        int ret;
        synchronized (this) {

            while (this.size == 0) {
                this.wait();
            }

            ret = array[haed];
            haed++;
            size--;
            if (haed == array.length) {
                this.haed = 0;
            }

            this.notify();
        }

        return ret;
    }

}

代碼分析

在這裏插入圖片描述
在這裏插入圖片描述

  • 詳細說一下爲什麼判斷空或者滿要使用while而不是使用if
    假設現在又三個線程 一個生產 倆個消費
    而且是消費快 生產慢
    此時倆個消費都會判斷爲空然後進入wait
    如果此時我們不小心使用了notiAll喚醒了所有等待的線程
    於是消費者1先得到鎖 執行了出隊列操作 生產者還沒來得及生產 消費者2就又獲取了鎖 此時剛剛生產了一個元素已經被消費者拿走了 當前已經是一個空隊列了
    如果再往下執行就會發生邏輯錯誤 結果就不可控了
  • 所以我們在判斷條件進行使用wait的時候 都推薦使用while去搭配而不是if
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章