您的位置:首页 > 编程语言 > Java开发

Java多线程/并发25、Exchanger线程数据交换

2017-05-07 15:19 561 查看
Exchanger用于线程间的数据交换。它提供一个同步点,在这个同步点两个线程可以交换彼此的数据。

这句话说到两个关键点:

Exchanger只能用于两个线程互相交换数据。如果有三个线程呢?对不起,臣妾做不到……

Exchanger会产生一个同步点。一个线程先执行到达同步点,就会阻塞,等到另一个线程。两个都到达同步点后,开始交换数据。线程方法中调用exchanger.exchange()的地方就是同步点。

来看例子:

在学校读书时做算术题,通常先用正常思维计算结果,然后换一种方式验算,两个结果一致就说明做对了。以前还见过打算盘打得好的人,可以用两只手打,一只手计算,一只手验算。典型的多线程……我也想学这门手艺,于是那位先生要我先试试左手写1,2,3,4,5,右手写5,4,3,2,1,然后我就没学了。。。。。。

下面的程序通过两个线程计算50*70的值,各自计算完后,通过exchanger交换结果,如果一致就算成功。

public class ExchangerDemo {
public static void main(String[] args) {
final Exchanger<Integer> exgr = new Exchanger<Integer>();
ExecutorService threadPool = Executors.newFixedThreadPool(2);
/*线程1用于计算结果*/
threadPool.execute(new Runnable() {
@Override
public void run() {
int result=50*70;
try {
System.out.println("线程"+Thread.currentThread().getName()+"计算50*70的结果是:"+result);

/*同步点。先到达的线程会在这里等侯*/
exgr.exchange(result);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
/*线程2用于计算并检验*/
threadPool.execute(new Runnable() {
@Override
public void run() {
int result=0;
for(int i=0;i<50;i++){
result+=70;
}
System.out.println("线程"+Thread.currentThread().getName()+"计算50*70的结果是:"+result);
try {
/*同步点。先到达的线程会在这里等侯*/
int result_FromOtherThread=exgr.exchange(result);
System.out.println("线程"+Thread.currentThread().getName()+"从另一个线程获取得值是:"+result_FromOtherThread);
if(result_FromOtherThread==result){
System.out.println("两边计算结果一样,验证成功");
}else{
System.out.println("两边计算结果不一样,验证失败");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}


输出:

线程pool-1-thread-1计算50*70的结果是:3500
线程pool-1-thread-2计算50*70的结果是:3500
线程pool-1-thread-2从另一个线程获取得值是:3500
两边计算结果一样,验证成功


可以把线程1的int result=50*70;改一下,看看输出什么。

如果两个线程有一个因为中断或崩溃没有到达exchange方法,另一个则会一直等待。如果担心有特殊情况发生,避免一直等待,可以使用
exchange(V x, long timeout, TimeUnit unit)
设置最大等待时长。

如上面例子中的第二个线程,只等待5秒:

exgr.exchange(result,5,TimeUnit.SECONDS);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: