SynchronousQueue 是不存储元素的同步队列,其核心是实现生产者与消费者间的直接交接:put 需等待 take、take 需等待 put,offer/poll 非阻塞但立即返回,size 始终为 0,适用于零缓冲的即时协作场景。

SynchronousQueue 是 Java 并发包(java.util.concurrent)中一种特殊的阻塞队列,它**不存储元素**——也就是说,它没有内部容量,不能“增”也不能“减”传统意义上的队列元素。
为什么说它不支持常规的“增减”操作?
它的设计目标是实现**直接交接(hand-off)**:每个插入操作(put)必须等待另一个线程执行对应的移除操作(take),反之亦然。没有缓冲空间,没有暂存元素。
-
offer(e)和put(e):不是“把元素加进去”,而是“尝试交给另一个正在等待取走它的线程”。如果此时没有匹配的消费者,offer立即返回false,put则阻塞直到有线程调用take。 -
poll()和take():不是“从队列里取出一个已有元素”,而是“尝试从某个正在等待交付的生产者那里接收一个元素”。如果没有匹配的生产者,poll返回null,take阻塞等待。 -
size()始终返回0;isEmpty()始终返回true—— 因为它真的不保存任何东西。
常见使用场景:线程间“一来一回”的即时协作
它适合用于需要严格配对、零延迟传递的场景,比如:
- 工作窃取线程池(如
ForkJoinPool内部)中任务的快速交接 - 生产者-消费者模型中要求“生产即消费”,不允许积压
- 构建无缓冲的信号通道(例如:一个线程通知另一个线程“我准备好了”,对方立即响应)
简单示例:put/take 配对才能完成一次传递
下面这段代码不会卡死,因为两个线程在彼此等待时完成了元素交接:
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
立即学习“Java免费学习笔记(深入)”;
SynchronousQueue<String> sq = new SynchronousQueue<>();
new Thread(() -> {
try { sq.put("hello"); } catch (InterruptedException e) {}
}).start();
new Thread(() -> {
try { System.out.println(sq.take()); } catch (InterruptedException e) {}
}).start();
// 输出:hello
但如果只调用 put 而没有对应 take,线程会一直阻塞;同理,只调用 take 也会阻塞。
基本上就这些 —— 它不是用来“增减元素”的队列,而是用来“促成一次原子性交接”的同步工具。


















