Skip to main content

交换器Exchanger

huhxAbout 1 minjavaConcurrency-ToolkitConcurrency

线程之间的协作姿势千姿百态,如果两个线程之间的数据想要互换这该如何实现?对头,Exchanger就是为此而生的。它可以在两个线程之间交换数据,而且只能是2个线程,线程多了还不行。今天我们就通过实例来学习一下Exchanger的用法。

使用

Exchanger是在两个任务之间交换对象的栅栏,当任务进入栅栏时,它们各自拥有一个对象。当他们离开时,它们都拥有之前由对方线程持有的对象。

Exchanger
Exchanger

分析

下面我们举个例子:两个人完成一笔交易,一手交钱,一手交货

public class ExchangerTest {
    final static Exchanger<String> exchanger = new Exchanger<>();

    public static void main(String[] args) {
        var executor = Executors.newCachedThreadPool();
        executor.execute(() -> doExchangeWork("金钱"));
        executor.execute(() -> doExchangeWork("货物"));

        executor.shutdown();
    }

    private static void doExchangeWork(String product) {
        try {
            System.out.println(Thread.currentThread().getName() + " 正在把 " + product + " 给出去, time: " + LocalDateTime.now());
            Thread.sleep(new Random().nextInt(1000));

            var receivedData = exchanger.exchange(product);

            System.out.println(Thread.currentThread().getName() + " 得到 " + receivedData + ", time: " + LocalDateTime.now());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

 














 







输出结果:

pool-1-thread-1 正在把 金钱 给出去, time: 2023-08-16T21:16:30.403456
pool-1-thread-2 正在把 货物 给出去, time: 2023-08-16T21:16:30.403454
pool-1-thread-1 得到 货物, time: 2023-08-16T21:16:30.952205
pool-1-thread-2 得到 金钱, time: 2023-08-16T21:16:30.952462

当线程1调用Exchange对象的exchange()方法后,它会进入阻塞状态直到线程2也调用了exchange()方法,然后两线程以安全的方式交换彼此的数据,之后线程12继续运行。

FAQ

总结

参考