java并发工具类-Exchanger
java并发工具类-Exchanger
Exchanger 简介
Exchange位于JUC包下面,主要是用于线程之间数据交换的工具类,经常用于管道设计和遗传算法中,Exchanger用于进行线程间的数据交换,它提供一个同步点,在这个同步点,两个线程可以交换彼此的数据。这两个线程通过exchange 方法交换数据,如果第一个线程先执行exchange 方法,它会一直等待第二个线程也执行exchange 方法,当两个线程都到达同步点时,这两个线程就可以交换数据。
可以将Exchange看做是一个双向数据传输的SynchronousQueue。
- 此类提供对外的操作是同步的;
- 用于成对出现的线程之间交换数据;
- 可以视作双向的同步队列;
- 可应用于基因算法、流水线设计等场景。
Exchanger 提供的方法
构造方法
/**
* Creates a new Exchanger.
*/
public Exchanger() {
participant = new Participant();
}
创建一个新的Exchange。
主要方法
这个类提供对外的接口非常简洁,一个无参构造函数,两个重载的范型exchange方法:
等待另外一个线程到达此交换点(除非当前线程被中断),将给定的对象x传送给该线程,并且接收该线程的对象。
public V exchange(V x) throws InterruptedException
等待另外一个线程到达此交换点(除非当前线程被中断,或者超出了指定的等待时间),将指定的对象x传送给该线程,同时接收该线程的对象。
public V exchange(V x, long timeout, TimeUnit unit) throws InterruptedException, TimeoutException
Exchanger的应用场景
Exchanger可以用于遗传算法,遗传算法里需要选出两个人作为交配对象,这时候会交换两人的数据,并使用交叉规则得出2个交配结果。
只要用于两个线程之间交换数据。
如果两个线程有一个没有到达exchange方法,则会一直等待,如果担心有特殊情况发生,避免一直等待,可以使用exchange(V x, long timeout, TimeUnit unit)设置最大等待时长。
案例
比如生活中两个人,一个人有零食,另一个人有钱,他们两个想等价交换,对好口号在某个地方相见,一个人先到了之后,必须等另一个人带着需要的东西来了之后,才能开始交换。
public class ExchangerTest {
public static void main(String[] args) {
Exchanger exchanger = new Exchanger();
ExecutorService service = Executors.newCachedThreadPool();
//线程1 拿着零食来交换
service.submit(() -> {
String data1 = "零食";
System.out.println("线程" + Thread.currentThread().getName() +
"正在把数据 " + data1 + " 换出去");
String data2 = null;
try {
System.out.println("正在交换等待10s");
Thread.sleep((long) Math.random() * 10000);
//开始交换数
data2 = (String) exchanger.exchange(data1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程 " + Thread.currentThread().getName() +
"换回的数据为 " + data2);
});
//线程2 拿着钱来交换
service.submit(() -> {
String data1 = "钱";
System.out.println("线程" + Thread.currentThread().getName() +
"正在把数据 " + data1 + " 交换出去");
String data2 = null;
try {
System.out.println("正在交换等待10s");
Thread.sleep((long) (Math.random() * 10000));
//开始交换数
data2 = (String) exchanger.exchange(data1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程 " + Thread.currentThread().getName() +
"交换回来的数据是: " + data2);
});
service.shutdown();
}
}
输出
线程pool-1-thread-1正在把数据 零食 换出去
正在交换等待10s
线程pool-1-thread-2正在把数据 钱 交换出去
正在交换等待10s
线程 pool-1-thread-2交换回来的数据是: 零食
线程 pool-1-thread-1换回的数据为 钱
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 牧马人的忧伤!
评论