并发编程系列之Exchanger

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> 并发编程系列之Exchanger

并发编程系列之Exchanger

前言

上面我们介绍了信号量,再来说说交换者,这个东西用的不是很多,所以一般也不被经常关注,但是我们还是最好了解下,下面我将从什么是Exchanger以及如何使用Exchanger两个方面谈谈这个用于线程间协调的工具类。

并发编程系列之Exchanger

什么是Exchanger?

Exchanger主要是用于线程之间进行数据交换的,提供一个同步点,在这个同步点,两个线程可以交换彼此的数据;两个线程通过Exchanger方法来进行交换,当第一个线程先执行Exchanger()方法,他会一直等待第二个线程也执行Exchanger方法,然后两个线程交换数据。

举个通俗点的例子,就例如,你和你女朋友一起去逛超市,然后进入超市之后,你俩约好每个人去买各自需要的用品,然后约好在结算台那里见面,不管你俩谁先买好东西到达服务台,都需要把东西放在服务台然后等待对方,当你俩都到达结账台时,你俩互相交换各自买的东西,看看对方都买了些啥(当然如果你跟你女朋友真是这么逛街的,估计也处不长,扯远了点),然后结账,完事。这个过程就是Exchanger交换数据过程,而你俩分别就是那两个线程。

并发编程系列之Exchanger

如何使用Exchanger?

首先我们需要一个创建一个交换者


ExchangerString exgr = new ExchangerString();

然后到达同步点,等待交换:


public V exchange(V x) throws InterruptedException {
        if (!Thread.interrupted()) {
            Object v = doExchange((x == null) ? NULL_ITEM : x, false, 0);
            if (v == NULL_ITEM)
                return null;
            if (v != CANCEL)
                return (V)v;
            Thread.interrupted(); // Clear interrupt status on IE throw
        }
        throw new InterruptedException();
    }

下面我们来看示例,模拟你和女朋友逛超市:


public class ExchangerDemo {
    // 超市结账服务台(同步点)
    private static final ExchangerString exgr = new ExchangerString();
    // 你和你女朋友
    private static ExecutorService threadPool = Executors.newFixedThreadPool(2);
    public static void main(String[] args) {
        System.out.println("逛街开始,行动!!!");
        threadPool.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("你进入超市");
                try {
                    String u = "电子产品";
                    System.out.println("你购买ok,到达服务台");
                    // 到达同步点,等待或者交换(所有线程都到达)
                    exgr.exchange(u);
                } catch (InterruptedException e) {
                }
            }
        });

        threadPool.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("女朋友进入超市");
                try {
                    String girlfriend = "化妆品";
                    // 交换购买物品   到达同步点,等待或者交换(所有线程都到达)
                    String u1 = exgr.exchange("girlfriend");
                    System.out.println("女朋友到达服务台,交换购买物品");
                    System.out.println("你购买的是:"
                            + u1 + ",女朋友购买的是:" + girlfriend);
                } catch (InterruptedException e) {
                }
            }
        });
        threadPool.shutdown();
    }
}

执行结果:

并发编程系列之Exchanger

当然还有一种情况,就是可能会你和你女朋友分开逛街的过程中,出现点状况,导致你买好东西之后,在服务台一直等她,她都没来(没来原因自己脑补),然后你也不能一直等下去啊,然后你就自己结账走人了,然后,然后,你就单身了…,对于这种情况,Exchanger提供了一个超时交换的方法,设置最大等待时间,源代码如下:


public V exchange(V x, long timeout, TimeUnit unit)
        throws InterruptedException, TimeoutException {
        if (!Thread.interrupted()) {
            Object v = doExchange((x == null) ? NULL_ITEM : x,
                                  true, unit.toNanos(timeout));
            if (v == NULL_ITEM)
                return null;
            if (v != CANCEL)
                return (V)v;
            if (!Thread.interrupted())
                throw new TimeoutException();
        }
        throw new InterruptedException();
    }
并发编程系列之Exchanger

原文始发于微信公众号(Justin的后端书架):

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> 并发编程系列之Exchanger


 上一篇
并发编程系列之CountDownLatch对战Cyclicbarrier 并发编程系列之CountDownLatch对战Cyclicbarrier
前言 前面我们介绍了并发容器和队列,今天我们来介绍几个非常有用的并发工具类,今天主要讲CountDownLatch和Cyclicbarrier这两个工具类,通过讲解并对比两个类的区别,OK,让我们开始今天的并发之旅吧。 什么是Count
2021-04-05
下一篇 
并发编程系列之Fork,Join 并发编程系列之Fork,Join
前言 上节我们讲了阻塞队列,Java中的并发容器就算有了个基本的认识,今天我们来介绍一种线程工作模式,叫Fork/Join,他是JDK7之后提供的一个并行执行框架,主要的思想我觉得是分而治之,将一个大的任务分成多个小的任务并
2021-04-05