Java Blocking Queue 實作範例

文章最後更新於 2023 年 3 月 16 日

Java的BlockingQueue是一個線程安全的佇列,它提供了阻塞式的添加和移除元素的操作,這些操作可以保證在多線程環境下的安全性。下面是一個基於陣列的BlockingQueue的實作範例:

import java.util.concurrent.locks.*;

public class ArrayBlockingQueue<T> {
  private final Lock lock = new ReentrantLock();
  private final Condition notFull = lock.newCondition();
  private final Condition notEmpty = lock.newCondition();
  private final Object[] items;
  private int putIndex;
  private int takeIndex;
  private int count;

  public ArrayBlockingQueue(int capacity) {
    if (capacity <= 0)
      throw new IllegalArgumentException("Capacity must be positive");
    items = new Object[capacity];
  }

  public void put(T item) throws InterruptedException {
    lock.lock();
    try {
      while (count == items.length) {
        notFull.await();
      }
      items[putIndex] = item;
      if (++putIndex == items.length) {
        putIndex = 0;
      }
      ++count;
      notEmpty.signal();
    } finally {
      lock.unlock();
    }
  }

  public T take() throws InterruptedException {
    lock.lock();
    try {
      while (count == 0) {
        notEmpty.await();
      }
      Object item = items[takeIndex];
      if (++takeIndex == items.length) {
        takeIndex = 0;
      }
      --count;
      notFull.signal();
      return (T) item;
    } finally {
      lock.unlock();
    }
  }
}

在這個範例中,我們使用了ReentrantLock和Condition來實現互斥和同步。當一個線程嘗試向佇列中添加元素時,如果佇列已滿,則該線程會進入等待狀態,直到有空間可以添加元素。同樣地,當一個線程嘗試從佇列中取出元素時,如果佇列為空,該線程會進入等待狀態,直到有元素可以取出。

這個實作範例是一個簡單的BlockingQueue的實現,它可以作為其他複雜佇列的基礎,如LinkedBlockingQueue和PriorityBlockingQueue。

關於作者

卡哥
卡哥
大家好,我是 Oscar(卡哥)。曾任 Yahoo 資深工程師(Lead Engineer),也是高智商組織 Mensa 的會員,擁有超過 15 年的軟體開發經驗。職涯中曾參與 Yahoo 關鍵字廣告、電子商務與搜尋相關專案,近年則在虛擬貨幣交易所專注於大數據與 AI 資料服務,帶領團隊開發具影響力的產品與解決方案。

在工作之外,我熱愛音樂,平時喜歡彈吉他、創作與演奏;運動方面偏好羽球、高爾夫球,也投入在美股與虛擬貨幣的投資領域。最享受的,是透過交流與分享,把知識與經驗轉化成更多可能性。