核心差异在于是否缓冲任务:SynchronousQueue逻辑容量恒为0,不保存任何任务,必须生产者与消费者同步交接;LinkedBlockingQueue是真实链表队列,可有界或无界,支持任务暂存与背压控制。

核心差异就一条:SynchronousQueue 不缓冲,LinkedBlockingQueue 缓冲。
缓冲能力的本质区别
SynchronousQueue 逻辑容量恒为 0,内部不保存任何任务。每次 put() 必须同步匹配一个 take(),像“手递手”交接,中间不留存。它不是容器,是通道。
LinkedBlockingQueue 是真实队列,用链表维护元素,可设容量(有界)或不设(默认 Integer.MAX_VALUE,即“无界”)。任务来了先入队暂存,等空闲线程来取,天然具备缓冲能力。
缓冲行为对线程池的影响
- SynchronousQueue:任务无法排队,必须立刻找到空闲线程或触发创建新线程。若 maximumPoolSize 较小或线程创建受限,容易触发拒绝策略(如 AbortPolicy)。
- LinkedBlockingQueue:任务可积压在队列中,缓解瞬时高峰;corePoolSize 线程处理完后会继续从队列取任务,maximumPoolSize 在默认配置下基本不生效(除非队列已满且有新任务到来)。
缓冲带来的并发与稳定性权衡
LinkedBlockingQueue 用两把独立锁(putLock / takeLock),允许生产与消费并行,吞吐稳定,适合容忍一定延迟、需背压控制的场景(如 Web 请求排队)。
SynchronousQueue 没有队列维护开销,延迟极低,但要求线程资源响应及时——它把“缓冲压力”转嫁给了线程创建机制,不适合任务处理慢或线程供给紧张的环境。
辅助验证:它们“不存东西”的证据
调用以下方法时,行为截然不同:
- isEmpty():SynchronousQueue 总返回 true;LinkedBlockingQueue 按实际返回。
- peek() / iterator():SynchronousQueue 总返回 null 或空迭代器;LinkedBlockingQueue 返回头结点或有效迭代器。
- remainingCapacity():SynchronousQueue 恒为 0;LinkedBlockingQueue 返回剩余空间数。










