返回

有限阻塞队列:同步并限制容量

Android

想象一下,你在一个繁忙的餐厅工作,食物从厨房源源不断地运出来,而服务员则不断地将菜品端到顾客的餐桌上。为了确保厨房和服务员之间不会产生混乱,需要一个系统来管理菜品流转。这就是有限阻塞队列的用武之地。

有限阻塞队列是一个线程安全的容器,它允许在两个线程之间同步地传输数据。在我们的餐厅场景中,厨房就相当于生产者线程,而服务员相当于消费者线程。厨房(生产者)将准备好的菜品放入队列中,而服务员(消费者)从队列中取出菜品。

关键特性

  • 有限容量: 队列的大小是有限的,由构造方法中的capacity参数指定。这意味着队列不能容纳超过capacity个元素。
  • 阻塞: 当队列已满时,生产者线程将被阻塞,直到队列中腾出空间为止。同样,当队列为空时,消费者线程将被阻塞,直到队列中出现元素为止。
  • 线程安全: 队列的方法是线程安全的,这意味着它们可以安全地在多线程环境中使用。

实施

实现一个有限阻塞队列需要同步机制,例如锁或信号量。在我们的代码示例中,我们使用了一个称为ReentrantLock的内置Java锁。

import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Condition;

class BoundedBlockingQueue {

    private final ReentrantLock lock = new ReentrantLock();
    private final Condition notEmpty = lock.newCondition();
    private final Condition notFull = lock.newCondition();

    private final Object[] items;
    private int head;
    private int tail;
    private int size;

    public BoundedBlockingQueue(int capacity) {
        items = new Object[capacity];
    }

    public void put(Object item) throws InterruptedException {
        lock.lock();
        try {
            while (size == items.length) {
                notFull.await();
            }
            items[tail] = item;
            tail = (tail + 1) % items.length;
            size++;
            notEmpty.signal();
        } finally {
            lock.unlock();
        }
    }

    public Object take() throws InterruptedException {
        lock.lock();
        try {
            while (size == 0) {
                notEmpty.await();
            }
            Object item = items[head];
            head = (head + 1) % items.length;
            size--;
            notFull.signal();
            return item;
        } finally {
            lock.unlock();
        }
    }
}

结论

有限阻塞队列在多线程环境中非常有用,它可以同步并限制两个线程之间的数据传输。通过使用适当的同步机制,我们可以确保数据的一致性和可靠性。在我们的餐厅场景中,有限阻塞队列确保菜品能够顺利地从厨房流向服务员,而不会造成混乱或丢失订单。