java队列如何阻塞
阻塞队列的实现方式
在Java中,可以通过java.util.concurrent包提供的阻塞队列实现阻塞操作。常见的阻塞队列包括ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue和SynchronousQueue。
关键方法:
put(E e):向队列尾部插入元素,若队列满则阻塞,直到空间可用。take():移除并返回队列头部元素,若队列空则阻塞,直到有元素可用。offer(E e, long timeout, TimeUnit unit):尝试插入元素,若队列满则等待指定时间后返回false。poll(long timeout, TimeUnit unit):尝试获取元素,若队列空则等待指定时间后返回null。
示例代码
使用ArrayBlockingQueue演示阻塞操作:
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class BlockingQueueExample {
public static void main(String[] args) {
BlockingQueue<String> queue = new ArrayBlockingQueue<>(3);
// 生产者线程
new Thread(() -> {
try {
queue.put("Task 1");
queue.put("Task 2");
queue.put("Task 3");
System.out.println("队列已满,尝试插入...");
queue.put("Task 4"); // 阻塞直到队列有空位
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}).start();
// 消费者线程
new Thread(() -> {
try {
Thread.sleep(2000); // 模拟延迟
System.out.println("取出: " + queue.take());
System.out.println("取出: " + queue.take());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}).start();
}
}
自定义阻塞队列
通过ReentrantLock和Condition手动实现阻塞逻辑:

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class CustomBlockingQueue<T> {
private final Queue<T> queue = new LinkedList<>();
private final int capacity;
private final ReentrantLock lock = new ReentrantLock();
private final Condition notEmpty = lock.newCondition();
private final Condition notFull = lock.newCondition();
public CustomBlockingQueue(int capacity) {
this.capacity = capacity;
}
public void put(T item) throws InterruptedException {
lock.lock();
try {
while (queue.size() == capacity) {
notFull.await(); // 队列满时阻塞
}
queue.add(item);
notEmpty.signal(); // 唤醒消费者
} finally {
lock.unlock();
}
}
public T take() throws InterruptedException {
lock.lock();
try {
while (queue.isEmpty()) {
notEmpty.await(); // 队列空时阻塞
}
T item = queue.remove();
notFull.signal(); // 唤醒生产者
return item;
} finally {
lock.unlock();
}
}
}
适用场景
- 生产者-消费者模型:协调生产速度和消费速度不一致的问题。
- 线程池任务队列:如
ThreadPoolExecutor使用阻塞队列管理待执行任务。 - 资源限制:通过固定容量队列控制资源并发访问。
注意事项
- 死锁风险:确保阻塞和唤醒逻辑配对,避免线程永久阻塞。
- 性能权衡:根据场景选择公平锁(
ReentrantLock(true))或非公平锁。






