同步队列(synchronousqueue)容量为0,任务无法缓存,提交即触发线程创建(未达maximumpoolsize时),适合低延迟突发场景;有界队列(如arrayblockingqueue)固定容量,任务先入队、满后才扩容,内存可控但可能丢任务或延迟上升。

同步队列(SynchronousQueue)和有界队列(如 ArrayBlockingQueue)在线程池中行为截然不同:前者不存任务,靠线程“手递手”交接;后者固定容量,任务必须排队等待。选错队列,轻则吞吐骤降,重则线程爆炸或内存溢出。
同步队列:零缓冲、高并发、强依赖线程供给
它本质是“通道”,不是“仓库”。容量为 0,offer() 总是立刻返回 false,线程池因此几乎每次提交任务都触发新建线程(只要未达 maximumPoolSize)。
- 适合短时、突发、低延迟场景,比如网关转发、RPC调用响应
- 必须配好
maximumPoolSize和拒绝策略(推荐AbortPolicy或自定义限流策略),否则容易创建过多线程压垮 CPU - 常见于
Executors.newCachedThreadPool(),核心线程数为 0,靠动态扩容应对负载
有界队列:可控缓冲、防资源耗尽、需权衡拒绝风险
典型代表是 ArrayBlockingQueue,构造时指定固定容量(如 100)。任务入队失败(offer() 返回 false)才会触发扩容逻辑——即新建非核心线程,直到达到最大线程数。
- 能有效限制内存占用,避免任务无限堆积
- 队列满后新任务会走拒绝策略,需根据业务容忍度选:
AbortPolicy(抛异常)、DiscardPolicy(静默丢弃)、CallerRunsPolicy(由提交线程自己执行) - 注意:手动指定小容量的
LinkedBlockingQueue(10)行为与ArrayBlockingQueue一致,别误以为“链表=无界”
关键差异:触发线程扩容的时机完全不同
同步队列:任务一来就尝试“交人”,没人接就新建线程 → 扩容频繁、响应快、内存稳、CPU压力大。
有界队列:先塞队列,塞不下才建线程 → 扩容保守、内存可控、CPU温和、但可能丢任务或延迟上升。
- 同步队列的线程增长是“被动响应型”:靠入队失败驱动
- 有界队列的线程增长是“缓冲耗尽型”:依赖明确的容量阈值
- 两者都不依赖定时检测或后台扫描,而是由
offer()的返回值实时决定下一步动作
实战选型建议
看你的系统瓶颈在哪:
- 如果 CPU 是瓶颈、任务轻量且突发性强,选
SynchronousQueue+ 合理maximumPoolSize - 如果堆内存紧张、任务对象较大(如含大 JSON 或 byte[])、需稳定控制资源,选
ArrayBlockingQueue或小容量LinkedBlockingQueue - 永远不要用默认无参的
LinkedBlockingQueue做高吞吐任务队列——表面无界,实为 OOM 温床
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











