SynchronousQueue 是容量为0的同步移交队列,生产者put()与消费者take()必须即时配对,元素不经过存储直接线程间传递,适用于命令响应、事件驱动等强时序零缓冲场景。
SynchronousQueue
不是传统意义上的队列,它不存储元素,而是作为线程间“手递手”传递任务或数据的通道——生产者必须等待消费者就绪才能交付,消费者也必须等待生产者出现才能获取。这种
即时配对、零缓冲
的特性,天然适合需要
变量实时传递、强时序控制、无中间状态残留
的场景,比如命令触发、事件响应、协程式流程编排等。
理解 SynchronousQueue 的核心行为
它内部没有容量(capacity = 0),每次
都会阻塞,直到另一个线程调用
;反之亦然。这不是“缓存后通知”,而是
直接线程交接
:
调用
的线程会挂起,直到有其他线程正在执行
一旦配对成功,item 不经过任何队列中转,直接从生产者栈帧传入消费者栈帧
不存在“多个任务堆积”或“旧值覆盖”问题——每次只能传递一个,且必须被立刻消费
实战:用 SynchronousQueue 实现命令-响应式变量传递
假设有一个主控线程下发参数(如 targetId、timeoutMs),工作线程需立即接收并执行,且不允许延迟或积压:
关键细节与避坑指南
实际使用中需注意以下几点,否则容易陷入死锁或逻辑错位:
必须成对出现
:每个
都要有对应
,否则一方永久阻塞。建议配合超时操作(
/
)防止卡死
不适合批量或异步解耦
:若想“发完就走”,SynchronousQueue 不适用——应换用
或
变量需线程安全封装
:虽然传递是原子的,但若 Map 中的 value 是可变对象(如 ArrayList),仍需确保消费者不与生产者并发修改同一实例;推荐传递不可变容器(
)或只读视图
支持公平策略
:构造时传
可启用 FIFO 公平模式(默认非公平),避免某些线程长期饥饿,在严格顺序场景下更可控
延伸:模拟轻量级协程通信
结合
与
,可在两个协作线程间建立单向“请求-应答”通道:
主线程通过 queue 发送请求,同时用
绑定专属响应通道
工作线程处理完后,将结果
到该线程局部的响应队列
主线程在发送后立即
自己的响应队列,实现“发起即等待结果”的同步语义,但底层仍是两线程协作
这种方式规避了 Future 的调度开销和回调嵌套,又比 wait/notify 更简洁明确,适合低延迟、高确定性的本地协同任务。
put()take()put(item)take()SynchronousQueueput()take()offer(item, timeout, unit)poll(timeout, unit)LinkedBlockingQueueConcurrentLinkedQueueMap.copyOf()trueThreadLocalSynchronousQueueThreadLocal> puttake()