转:https://blog.csdn.net/tongdanping/article/details/79589253
Exchanger(交换者)
Exchanger是一个线程间提供数据交换功能的写作工具,他提供了一个同步点,在这个同步点,两个线程可以交换彼此的数据。线程间通过调用excahange()方法交换数据,如果第一个线程先到达同步点,执行exchange方法,那么他会一直在同步点等待第二个线程到达同步点,第二个线程也执行exchange方法,这时两个线程都到达同步点,可以交换彼此的数据。
使用:
(1)创建一个Exchanger对象;
(2)在要交换(同步)数据的同步点调用excr.exchange( )方法
public class ExchangerTest {
static Exchanger<String> exc = new Exchanger<>(); //创建一个Exchanger对象;
public static void main(String[] args) throws InterruptedException {
new Thread(new Runnable() {
@Override
public void run() {
try{
String A= "银行流水A";
//在要交换(同步)数据的同步点调用excr.exchange()方法
String B = exc.exchange(A);
System.out.println("A的视角: A、B流水是否一致:" + A.equals(B) + " A录入的是:" + A + " B录入的是:" + B);
}
catch(Exception e){
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
try{
String B= "银行流水B";
//在要交换(同步)数据的同步点调用excr.exchange()方法
String A = exc.exchange(B);
System.out.println("B的视角: A、B流水是否一致:" + A.equals(B) + " A录入的是:" + A + " B录入的是:" + B);
}
catch(Exception e){
e.printStackTrace();
}
}
}).start();
}
}
输出结果:
A的视角: A、B流水是否一致:false A录入的是:银行流水A B录入的是:银行流水B
B的视角: A、B流水是否一致:false A录入的是:银行流水A B录入的是:银行流水B
可以看出,Exchanger的“交换”更偏向于数据的同步与共享,而不是“你的给我,我的给你”这样有来有回的交换,是“你知道一个信息,我知道另一个消息,我们彼此交换了信息,那么我们就都知道了两个消息”。如果不愿意在同步点一直等待另一个线程,那么可以用设置等待时间的exchange方法:excr.exchange(V x, long timeout, timeUnit unit)。
*注意:
Exchanger交换数据是成对的交换;
Exchanger可以看做双向的同步队列,一个线程从个队列头部进行操作,一个从个队列尾部进行操作;
使用场景:
需要数据交换共享的场景,例如遗传算法中,需要选择两个人来交配,交换两人的数据并根据交换规则来得到交配结果,再例如用于校对工作,交换两个线程的数据,用于校对两个线程的数据是否相等;