LinkedTransferQueue是Java中专为“传递式”协作设计的无界线程安全队列,核心是transfer()方法——生产者阻塞直至消费者真正取走元素,实现手递手交付;支持tryTransfer和超时transfer,适用于请求-响应、背压等强同步场景,不适用于纯缓冲。

LinkedTransferQueue 是 Java 并发包(java.util.concurrent)中一个无界、线程安全的队列,专为“传递式”场景设计——即生产者不希望只是把元素放入队列就结束,而是等待消费者**真正取走**该元素后才继续。它比普通阻塞队列(如 LinkedBlockingQueue)在某些协作型生产-消费模型中更高效、语义更精确。
理解 TransferQueue 的核心语义:transfer() 是关键
普通队列的 put() 或 offer() 只负责入队;而 LinkedTransferQueue 提供了 transfer(E e) 方法:调用线程会**阻塞直到有另一个线程调用 take() 或 poll() 取走该元素**。这实现了真正的“手递手”传递,避免了元素在队列中闲置,减少了内存占用和上下文切换开销。
它还支持非阻塞的 tryTransfer(E e)(立即返回是否成功)和带超时的 transfer(E e, long timeout, TimeUnit unit),灵活适配不同等待策略。
典型使用场景:请求-响应式协作
适合需要强同步配合的场景,例如:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
- 工作线程提交任务后,必须等结果线程处理完并返回响应,才能继续
- 网络请求发起方与回调处理器分离,但要求请求对象“交付即生效”
- 流式数据处理中,上游等待下游确认接收,实现背压(backpressure)信号
注意:它不适合高吞吐、低延迟的纯缓冲场景(此时 ArrayBlockingQueue 或 SynchronousQueue 可能更合适),它的优势在于语义明确的同步点。
基础用法示例:模拟任务交付与响应
以下是一个简化但完整的协作示例:
LinkedTransferQueue<String> queue = new LinkedTransferQueue<>();
// 生产者线程:发送请求并等待被取走
new Thread(() -> {
try {
System.out.println("Producer: sending 'task-1'");
queue.transfer("task-1"); // 阻塞,直到消费者取走
System.out.println("Producer: confirmed delivery");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}).start();
// 消费者线程:取走并处理
new Thread(() -> {
try {
String task = queue.take(); // 或 poll(),但 take 更常见于等待
System.out.println("Consumer: received '" + task + "', processing...");
// 模拟处理
Thread.sleep(500);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}).start();
运行时,“confirmed delivery” 一定在 “received … processing…” 之后打印,体现了严格的交付顺序保证。
性能与注意事项
- 它是无界的,但
transfer()调用本身不会导致内存无限增长——因为未被取走的元素不会长期滞留;若消费者长期不取,生产者线程会一直阻塞,天然形成反压 - 内部基于无锁算法(Lock-Free),在高并发下比加锁队列扩展性更好
- 不要混用
put()/offer()和transfer():前者是“存”,后者是“交”,语义冲突易导致逻辑混乱 - 若消费者用
poll()(非阻塞)取元素,而生产者用transfer(),可能因时机错过导致生产者无限等待——应确保消费者至少使用take()或poll(long, TimeUnit)


















