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會員,超過十年的工作經驗,服務過Yahoo關鍵字廣告業務部門、電子商務及搜尋部門,喜歡彈吉他玩音樂,也喜歡投資美股、虛擬貨幣,樂於與人分享交流!

如果對文章內容有任何問題,歡迎在底下留言讓我知道。
如果你喜歡我的文章,可以按分享按鈕,讓更多的人看見我的文章。