java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java 阻塞队列

Java 阻塞队列的7种类型小结

作者:@zcc@

Java中的阻塞队列是线程安全的队列结构,包括ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue、DelayQueue、SynchronousQueue、LinkedTransferQueue和LinkedBl,下面就来具体介绍一下,感兴趣的可以了解一下

在 Java 中,阻塞队列(BlockingQueue) 是一种线程安全的队列结构,用于实现生产者-消费者模式。它的核心特性是在队列为空时阻塞消费者线程,在队列满时阻塞生产者线程,从而自动协调线程之间的协作。

阻塞队列的核心特性

  1. 线程安全:所有操作(如 puttake)都是线程安全的。
  2. 阻塞操作
    • 队列满时:生产者线程阻塞(等待消费者消费)。
    • 队列空时:消费者线程阻塞(等待生产者生产)。
  3. 超时控制:支持带超时时间的操作(如 offer(timeout, unit)poll(timeout, unit))。
  4. 公平策略:部分实现(如 ArrayBlockingQueue)支持公平锁,防止线程饥饿。

Java 中的 7 种阻塞队列

以下是 Java 提供的 7 种阻塞队列及其特点和适用场景:

1. ArrayBlockingQueue(有界队列)

2. LinkedBlockingQueue(有界/无界队列)

3. PriorityBlockingQueue(无界优先级队列)

4. DelayQueue(延迟队列)

5. SynchronousQueue(同步队列)

6. LinkedTransferQueue(无界队列)

7. LinkedBlockingDeque(双向阻塞队列)

阻塞队列的核心方法

方法行为抛出异常返回布尔值阻塞超时阻塞
add(E e)插入元素队列满时抛异常-
offer(E e)插入元素队列满时返回 false-
offer(E e, long timeout, TimeUnit unit)插入元素超时后返回 false-
put(E e)插入元素--
remove()移除元素队列空时抛异常-
poll()移除元素队列空时返回 null-
poll(long timeout, TimeUnit unit)移除元素超时后返回 null-
take()移除元素--

如何选择阻塞队列?

  1. 有界 vs 无界:
    • 有界队列(如 ArrayBlockingQueue):防止内存溢出,需合理设置容量。
    • 无界队列(如 LinkedBlockingQueue):可能导致任务堆积,需结合拒绝策略使用。
  2. 优先级需求:
    • 使用 PriorityBlockingQueue 实现优先级排序。
  3. 延迟任务:
    • 使用 DelayQueue 实现定时或延迟执行。
  4. 高性能场景:
    • SynchronousQueue 适合高吞吐量的短任务。
    • LinkedTransferQueue 适合快速传递任务的场景。

示例:使用阻塞队列实现生产者-消费者模型

import java.util.concurrent.*;

public class ProducerConsumerExample {
    public static void main(String[] args) {
        BlockingQueue<String> queue = new LinkedBlockingQueue<>(10);

        // 生产者线程
        Thread producer = new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    String task = "Task-" + i;
                    queue.put(task); // 队列满时阻塞
                    System.out.println("Produced: " + task);
                    Thread.sleep(100);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

        // 消费者线程
        Thread consumer = new Thread(() -> {
            try {
                while (true) {
                    String task = queue.take(); // 队列空时阻塞
                    System.out.println("Consumed: " + task);
                    Thread.sleep(200);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

        producer.start();
        consumer.start();
    }
}

注意事项

  1. 避免内存泄漏
    • 使用无界队列时,需结合线程池的拒绝策略(如 CallerRunsPolicy)。
  2. 公平性
    • ArrayBlockingQueue 支持公平锁(构造函数传入 true)。
  3. 线程中断
    • 阻塞操作(如 put/take)会响应中断,需捕获 InterruptedException

通过合理选择阻塞队列类型,可以高效地实现线程间的协作,解决生产者-消费者问题。

到此这篇关于Java 阻塞队列的7种类型小结的文章就介绍到这了,更多相关Java 阻塞队列内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文