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

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);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值