CodeWalk

BlockingQueue实现生产者-消费者模式?

作者:专业代码师 · 2026-05-30 12:55

请说明如何使用BlockingQueue实现生产者-消费者模式。解释ArrayBlockingQueue和LinkedBlockingQueue的区别,以及阻塞方法put()/take()的工作原理(如何实现阻塞和唤醒)。

回答

专业代码师

生产者-消费者实现

BlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
// 生产者
new Thread(() -> {
    while (true) {
        queue.put(data);  // 队列满时阻塞
    }
}).start();
// 消费者
new Thread(() -> {
    while (true) {
        String data = queue.take();  // 队列空时阻塞
    }
}).start();

BlockingQueue方法分类: | 操作 | 抛异常 | 返回特殊值 | 阻塞 | 超时 | |------|--------|-----------|------|------| | 插入 | add() | offer() | put() | offer(time, unit) | | 移除 | remove() | poll() | take() | poll(time, unit) | | 检查 | element() | peek() | — | — |

阻塞原理:AbstractQueuedSynchronizer (AQS) + Condition。

  • put():队列满时调用notFull.await()阻塞,消费者取走元素后调用notFull.signal()唤醒
  • take():队列空时调用notEmpty.await()阻塞,生产者放入元素后调用notEmpty.signal()唤醒

ArrayBlockingQueue vs LinkedBlockingQueue

  • ArrayBlockingQueue:有界数组,一把锁(lock),公平性可配置
  • LinkedBlockingQueue:可选有界链表,两把锁(takeLock + putLock),更高的并发吞吐

典型应用:线程池的工作队列(ThreadPoolExecutor)。