Oracle 官方文档
package java.util.concurrent.Exchanger;
A synchronization point at which threads can pair and swap elements within pairs. Each thread presents some object on entry to the exchange method, matches with a partner thread, and receives its partner’s object on return. An Exchanger may be viewed as a bidirectional form of a SynchronousQueue. Exchangers may be useful in applications such as genetic algorithms and pipeline designs.
Sample Usage: Here are the highlights of a class that uses an Exchanger to swap buffers between threads so that the thread filling the buffer gets a freshly emptied one when it needs it, handing off the filled one to the thread emptying the buffer.
一个在配对的线程间可以交换元素的同步点。每一个线程在调用exchange方法的时候提供一些对象,配对的另一个线程接收它搭档的对象并返回。Exchanger会被看作是一个双向的同步队列。Exchangers在程序中是非常有用的,比如可以用在泛型算法和管道设计。
示例用法:该类的亮点是可以使用Exchanger在两线程之间交换数据,只要它需要它就可以使用一个新的空的缓冲区来填充数据,并且将填充好的对象传递给另一个空缓冲区的线程。
Memory consistency effects: For each pair of threads that successfully exchange objects via an Exchanger, actions prior to the exchange() in each thread happen-before those subsequent to a return from the corresponding exchange() in the other thread.
内存一致性影响:每一个通过Exchanger配对并成功交换对象的线程,当其它配对的线程调用了exchange之后,所有exchange之前的操作都会成为它后续的返回。这句好难翻译,不知道对不对。
简介
Exchanger可以在两个线程之间交换数据,只能是2个线程,他不支持更多的线程之间互换数据。
当线程A调用Exchange对象的exchange()方法后,他会陷入阻塞状态,直到线程B也调用了exchange()方法,然后以线程安全的方式交换数据,之后线程A和B继续运行。
测试用例
package com.demo.test;
import java.util.concurrent.Exchanger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExchangerDemo {
public static void main(String[] args) {
final int LOOP_COUNT = 5;
final Exchanger<String> exchanger = new Exchanger<>();
ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.execute(new Runnable() {
@Override
public void run() {
for (int i = 0; i < LOOP_COUNT; i++) {
final String origin = "A(" + i + ")";
try {
System.out.println(origin + " begin exchange");
String result = exchanger.exchange(origin);
System.out.println(origin + " print " + result);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
executorService.execute(new Runnable() {
@Override
public void run() {
for (int i = 0; i < LOOP_COUNT; i++) {
final String origin = "B(" + i + ")";
try {
System.out.println(origin + " begin exchange");
String result = exchanger.exchange(origin);
System.out.println(origin + " print " + result);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
}
}
运行结果
A(0) begin exchange
B(0) begin exchange
B(0) print A(0)
B(1) begin exchange
A(0) print B(0)
A(1) begin exchange
A(1) print B(1)
A(2) begin exchange
B(1) print A(1)
B(2) begin exchange
B(2) print A(2)
B(3) begin exchange
A(2) print B(2)
A(3) begin exchange
A(3) print B(3)
A(4) begin exchange
B(3) print A(3)
B(4) begin exchange
B(4) print A(4)
A(4) print B(4)