当前位置: 代码迷 >> 综合 >> Exchanger 介绍及应用详解
  详细解决方案

Exchanger 介绍及应用详解

热度:36   发布时间:2024-01-17 01:24:49.0

??Exchanger用于线程间进行通信、数据交换。Exchanger提供了一个同步点exchange方法,两个线程调用exchange方法时,无论调用时间先后,两个线程会互相等到线程到达exchange方法调用点,此时两个线程可以交换数据,将本线程产出数据传递给对方。

??演示示例:

package com.securitit.serialize.juc;import java.util.concurrent.Exchanger;public class ExchangerTester {
    // Exchanger实例.private static final Exchanger<String> exchanger = new Exchanger<String>();public static void main(String[] args) {
    // 模拟阻塞线程.new Thread(() -> {
    try {
    String wares = "红烧肉";System.out.println(Thread.currentThread().getName() + "商品方正在等待金钱方,使用货物兑换为金钱.");Thread.sleep(2000);String money = exchanger.exchange(wares);System.out.println(Thread.currentThread().getName() + "商品方使用商品兑换了" + money);} catch (InterruptedException ex) {
    ex.printStackTrace();}}).start();// 模拟阻塞线程.new Thread(() -> {
    try {
    String money = "人民币";System.out.println(Thread.currentThread().getName() + "金钱方正在等待商品方,使用金钱购买食物.");Thread.sleep(4000);String wares = exchanger.exchange(money);System.out.println(Thread.currentThread().getName() + "金钱方使用金钱购买了" + wares);} catch (InterruptedException ex) {
    ex.printStackTrace();}}).start();}}

??输出结果:

Thread-0商品方正在等待金钱方,使用货物兑换为金钱.
Thread-1金钱方正在等待商品方,使用金钱购买食物.
Thread-0商品方使用商品兑换了人民币
Thread-1金钱方使用金钱购买了红烧肉

??从结果可以看出,线程Thread-0首先调用了exchange方法,等待线程Thread-1到达exchange方法。当线程Thread-0和Thread-1两者都到达exchange方法时,通过exchange进行了数据交换。从结果可以看出,两个都拿到了对方传递的数据。

??演示示例:

??接下来演示public V exchange(V x, long timeout, TimeUnit unit) throws InterruptedException, TimeoutException;

package com.securitit.serialize.juc;import java.util.concurrent.Exchanger;
import java.util.concurrent.TimeUnit;public class ExchangerTimeTester {
    // Exchanger实例.private static final Exchanger<String> exchanger = new Exchanger<String>();public static void main(String[] args) {
    // 模拟阻塞线程.new Thread(() -> {
    try {
    String wares = "红烧肉";System.out.println(Thread.currentThread().getName() + "商品方正在等待金钱方,使用货物兑换为金钱.");Thread.sleep(2000);String money = exchanger.exchange(wares, 1000, TimeUnit.MILLISECONDS);System.out.println(Thread.currentThread().getName() + "商品方使用商品兑换了" + money);} catch (Exception ex) {
    ex.printStackTrace();}}).start();// 模拟阻塞线程.new Thread(() -> {
    try {
    String money = "人民币";System.out.println(Thread.currentThread().getName() + "金钱方正在等待商品方,使用金钱购买食物.");Thread.sleep(4000);String wares = exchanger.exchange(money);System.out.println(Thread.currentThread().getName() + "金钱方使用金钱购买了" + wares);} catch (Exception ex) {
    ex.printStackTrace();}}).start();}}

??输出结果:

Thread-0商品方正在等待金钱方,使用货物兑换为金钱.
Thread-1金钱方正在等待商品方,使用金钱购买食物.
java.util.concurrent.TimeoutExceptionat java.util.concurrent.Exchanger.exchange(Exchanger.java:626)at com.securitit.serialize.juc.ExchangerTimeTester.lambda$0(ExchangerTimeTester.java:18)at java.lang.Thread.run(Thread.java:748)

??public V exchange(V x, long timeout, TimeUnit unit) throws InterruptedException, TimeoutException;API中,若阻塞线程等待超过指定时间,则会抛出异常。