Java 中的 阻塞队列(BlockingQueue) 是 java.util.concurrent
包中提供的一种线程安全的队列实现。它支持在队列为空时阻塞获取操作,在队列满时阻塞插入操作。以下是 Java 中常见的阻塞队列及其特点:
1. ArrayBlockingQueue
- 特点:
- 基于数组实现的有界阻塞队列。
- 队列容量固定,创建时需要指定容量。
- 支持公平锁和非公平锁(默认是非公平锁)。
- 适用场景:
- 适合需要固定大小的队列场景。
2. LinkedBlockingQueue
- 特点:
- 基于链表实现的可选有界或无界阻塞队列。
- 如果不指定容量,默认是无界队列(
Integer.MAX_VALUE
)。 - 吞吐量通常高于
ArrayBlockingQueue
。
- 适用场景:
- 适合任务队列、线程池任务缓冲等场景。
3. PriorityBlockingQueue
- 特点:
- 基于堆实现的无界阻塞队列。
- 元素必须实现
Comparable
接口,或者通过构造函数传入Comparator
。 - 队列中的元素按优先级排序,优先级高的元素先出队。
- 适用场景:
- 适合需要按优先级处理任务的场景。
4. DelayQueue
- 特点:
- 基于优先级队列实现的无界阻塞队列。
- 元素必须实现
Delayed
接口,指定延迟时间。 - 只有延迟时间到期的元素才能被取出。
- 适用场景:
- 适合定时任务调度、缓存过期等场景。
- 示例代码:
class DelayedElement implements Delayed { private String data; private long delayTime; public DelayedElement(String data, long delayTime) { this.data = data; this.delayTime = System.currentTimeMillis() + delayTime; } @Override public long getDelay(TimeUnit unit) { return unit.convert(delayTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS); } @Override public int compareTo(Delayed o) { return Long.compare(this.delayTime, ((DelayedElement) o).delayTime); } @Override public String toString() { return data; } } BlockingQueue<DelayedElement> queue = new DelayQueue<>(); queue.put(new DelayedElement("Task 1", 3000)); // 3秒后到期 queue.put(new DelayedElement("Task 2", 1000)); // 1秒后到期 System.out.println(queue.take()); // 1秒后输出 "Task 2" System.out.println(queue.take()); // 3秒后输出 "Task 1"
5. SynchronousQueue
- 特点:
- 不存储元素的阻塞队列。
- 每个插入操作必须等待另一个线程的移除操作,反之亦然。
- 适合直接传递任务的场景。
- 适用场景:
- 适合线程之间直接传递数据的场景,如线程池的任务传递。
- 示例代码:
BlockingQueue<String> queue = new SynchronousQueue<>(); new Thread(() -> { try { System.out.println("Thread 1 putting item"); queue.put("Item"); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); new Thread(() -> { try { Thread.sleep(1000); System.out.println("Thread 2 taking item: " + queue.take()); } catch (InterruptedException e) { e.printStackTrace(); } }).start();
6. LinkedTransferQueue
- 特点:
- 基于链表实现的无界阻塞队列。
- 支持
transfer()
方法,生产者可以等待消费者取走元素后再返回。 - 性能优于
SynchronousQueue
和LinkedBlockingQueue
。
- 适用场景:
- 适合需要高效传递任务的场景。
- 示例代码:
TransferQueue<String> queue = new LinkedTransferQueue<>(); new Thread(() -> { try { System.out.println("Thread 1 transferring item"); queue.transfer("Item"); // 等待消费者取走 System.out.println("Thread 1 transfer complete"); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); new Thread(() -> { try { Thread.sleep(1000); System.out.println("Thread 2 taking item: " + queue.take()); } catch (InterruptedException e) { e.printStackTrace(); } }).start();
7. 总结
ArrayBlockingQueue
:固定大小的有界队列,适合需要控制队列大小的场景。LinkedBlockingQueue
:可选有界或无界队列,适合任务队列和线程池缓冲。PriorityBlockingQueue
:无界优先级队列,适合按优先级处理任务的场景。DelayQueue
:无界延迟队列,适合定时任务调度。SynchronousQueue
:不存储元素的队列,适合直接传递任务。LinkedTransferQueue
:高效的无界队列,支持生产者等待消费者。
THE END
暂无评论内容