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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/soonfly/article/details/71330762

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);

猜你喜欢

转载自blog.csdn.net/soonfly/article/details/71330762