BlockingQueue与SynchronousQueue

BlockingQueue

BlockingQueue 是一个支持阻塞操作 的队列接口,位于 java.util.concurrent 包中。它的典型应用就是生产者-消费者模型

需要首先给队列设置容量

BlockingQueue<String> queue = new ArrayBlockingQueue<>(3); // 容量=3

BlockingQueue 的四组 API

1. 抛异常

  • 当队列满时,再 add() 会抛异常;
  • 当队列空时,再 remove() 会抛异常。
scss 复制代码
add(e)       // 插入元素,成功返回 true,满时抛 IllegalStateException
remove()     // 移除队首元素,空时抛 NoSuchElementException
element()    // 查看队首元素,空时抛 NoSuchElementException

2. 返回特殊值

  • 满了插入失败返回 false
  • 空了移除失败返回 null
scss 复制代码
offer(e)     // 插入元素,成功返回 true,满时返回 false
poll()       // 移除队首元素,空时返回 null
peek()       // 查看队首元素,空时返回 null

3. 一直阻塞

  • 满了 put() 会一直阻塞,直到队列有空间;
  • 空了 take() 会一直阻塞,直到队列有元素。
scss 复制代码
put(e)       // 插入元素,满时阻塞
take()       // 移除并返回队首元素,空时阻塞

4.超时退出

  • 满了 offer(e, time, unit) 会等待指定时间,超时返回 false
  • 空了 poll(time, unit) 会等待指定时间,超时返回 null
scss 复制代码
offer(e, 2, TimeUnit.SECONDS)   // 等待 2 秒插入,失败返回 false
poll(2, TimeUnit.SECONDS)       // 等待 2 秒取出,失败返回 null
操作类型 抛异常 特殊值 阻塞 超时
插入 add(e) offer(e) put(e) offer(e, time, unit)
移除 remove() poll() take() poll(time, unit)
检查队首 element() peek() ------ ------

适合场景

  • 抛异常:适合严格要求,必须处理异常的场景。
  • 返回特殊值:适合可以容忍失败的场景。
  • 阻塞:适合生产者-消费者模型,不急着返回,等资源可用。
  • 超时:适合对实时性有要求的场景,不能无限等待。

SynchronousQueue

SynchronousQueue 是 Java 并发包里一个 非常特殊的 BlockingQueue 。它和其他 BlockingQueue(如 ArrayBlockingQueueLinkedBlockingQueue)不一样,它的容量永远是 0,没有任何内部缓冲。

特点

  1. 容量为 0
    • 不能存放任何元素。
    • put() 一个元素时,必须有另一个线程正在 take(),否则会阻塞。
    • take() 时也必须有线程 put(),否则也会阻塞。
  1. 一手交钱一手交货
    • 类似一个"当面交易"的模型。
    • 生产者线程和消费者线程必须同时到场,才能完成元素的交接。
  1. 线程间直接传递数据
    • 没有缓存区,数据不存储,而是 直接在两个线程之间传递

API 行为

  • put(e):如果没有消费者在等待,阻塞。
  • take():如果没有生产者在等待,阻塞。
  • offer(e, timeout, unit):在超时时间内,如果有消费者等待就成功,否则返回 false
  • poll(timeout, unit):在超时时间内如果有生产者等待就取到数据,否则返回 null

使用场景

  1. 线程间直接交换消息
    • 两个线程需要强同步(例如生产者和消费者一对一交接)。
  1. 线程池的工作队列(Executors.newCachedThreadPool 默认使用它)
    • 因为 SynchronousQueue 不存储任务,提交的任务必须马上被某个线程取走执行,如果没有空闲线程,就创建新线程。
    • 这也是为什么 CachedThreadPool 会无限制创建线程的原因。
相关推荐
野犬寒鸦1 天前
从零起步学习并发编程 || 第一章:初步认识进程与线程
java·服务器·后端·学习
我爱娃哈哈1 天前
SpringBoot + Flowable + 自定义节点:可视化工作流引擎,支持请假、报销、审批全场景
java·spring boot·后端
李梨同学丶1 天前
0201好虫子周刊
后端
思想在飞肢体在追2 天前
Springboot项目配置Nacos
java·spring boot·后端·nacos
Loo国昌2 天前
【垂类模型数据工程】第四阶段:高性能 Embedding 实战:从双编码器架构到 InfoNCE 损失函数详解
人工智能·后端·深度学习·自然语言处理·架构·transformer·embedding
ONE_PUNCH_Ge2 天前
Go 语言泛型
开发语言·后端·golang
良许Linux2 天前
DSP的选型和应用
后端·stm32·单片机·程序员·嵌入式
不光头强2 天前
spring boot项目欢迎页设置方式
java·spring boot·后端
怪兽毕设2 天前
基于SpringBoot的选课调查系统
java·vue.js·spring boot·后端·node.js·选课调查系统
学IT的周星星2 天前
Spring Boot Web 开发实战:第二天,从零搭个“会卖萌”的小项目
spring boot·后端·tomcat