SynchronousQueue的公平性指线程匹配是否遵循FIFO:公平模式用TransferQueue(队首匹配,无饥饿),非公平模式用TransferStack(栈顶匹配,高吞吐但可能饥饿);构造时指定,运行时通过transferer字段类型判断。

SynchronousQueue 的“公平性”不是指锁的公平,而是指线程等待顺序是否遵循 FIFO。它直接影响变量匹配(即 put 与 take 的配对)的行为逻辑——核心差异就落在内部结构上:非公平用栈(TransferStack),公平用队列(TransferQueue)。
匹配起点不同:栈顶 vs 队首
非公平模式下,新来的线程总是尝试与栈顶等待者匹配。后到的 put 可能立刻和刚阻塞的 take 配对,跳过前面更早等待的线程;而公平模式强制从队首开始扫描,确保等待最久的线程优先被服务。
- 栈结构天然支持快速压入/弹出,适合高吞吐场景,但可能让长时等待线程“饿着”
- 队列结构需维护链表头尾指针,插入和匹配开销略高,但行为可预测、无饥饿风险
匹配过程不可见但决定行为
无论哪种模式,匹配都发生在 transfer() 方法中,由 Transferer 子类完成。关键不是“谁先放数据”,而是“谁先被选中参与配对”:
- TransferStack 中,每个节点(SNode)记录 match 字段,用于唤醒对方线程并传递数据
- TransferQueue 中,节点(QNode)通过 next 指针串成链,匹配按 head→next 顺序推进
- 两者都不保存实际元素值,只保存线程引用和匹配状态
如何确认当前用的是哪一种
不能靠 size()、isEmpty() 或 toString() 判断——它们全返回 0 或 true,毫无区分度。
- 构造时明确指定:
new SynchronousQueue(true)→ 公平(TransferQueue);new SynchronousQueue()或new SynchronousQueue(false)→ 非公平(TransferStack) - 运行时检查 transferer 字段类型(需同包或通过 Unsafe):
transferer instanceof TransferQueue表示公平,transferer instanceof TransferStack表示非公平
变量匹配的本质是线程协作,不是数据暂存
SynchronousQueue 里没有“待匹配变量”的集合。所谓匹配,是两个线程在 transfer 调用中通过 CAS 修改共享节点状态(如 match 字段)、再互相 unpark 实现的即时握手。栈快在局部性好、缓存友好;队列稳在顺序可控、延迟可预期。

















