线程交换数据

Exchanger 简介:

Exchanger 提供了两个公开方法:

 

 1、只带泛型 V(交换的数据对象)的方法,线程一直阻塞,直到其他任意线程和它交换数据,或者被线程中断;

2、另外一个带时间的方法,如果超过设置时间还没有线程和它交换数据,就会抛出 TimeoutException 异常;

 

private static void test1() {
    Exchanger exchanger = new Exchanger();

    new Thread(() -> {
        try {
            Object data = "-公众号Java技术栈AAA";
            System.out.println(Thread.currentThread().getName() + data);

            // 开始交换数据
            data = exchanger.exchange(data);
            System.out.println(Thread.currentThread().getName() + data);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }).start();

    new Thread(() -> {
        try {
            Object data = "-公众号Java技术栈BBB";
            System.out.println(Thread.currentThread().getName() + data);

            // 开始交换数据
            data = exchanger.exchange(data);
            System.out.println(Thread.currentThread().getName() + data);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }).start();
}

这段代码的逻辑:

1、创建并启动两个线程;

2、进行数据交换前先打印出自己线程的数据;

3、进行数据交换;

4、打印数据交换之后的数据;

输出结果:

从结果可以看出,线程 0、1 分别先打印出 A、B,数据交换之后,打印出了 B、A,数据交换正常!

 

超时数据交换

上面演示了两个线程的正常交换,下面再来一个带超时的示例:

private static void test2() {
    Exchanger exchanger = new Exchanger();

    new Thread(() -> {
        try {
            Object data = "-公众号Java技术栈AAA";
            System.out.println(Thread.currentThread().getName() + data);

            // 开始交换数据
            data = exchanger.exchange(data, 3000L, TimeUnit.MILLISECONDS);
            System.out.println(Thread.currentThread().getName() + data);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }).start();
}

现在只启动了一个线程,并且设置了超时时间 3 秒。

输出结果:

 

 

首先线程输出了自己的数据,然后 3 秒后,并没有其他线程和它交换数据,所以抛出了超时异常,最后线程结束运行。

 

中断数据交换

线程开始交换数据后,会一直阻塞直到其他任意线程和它交换数据,或者被中断、超时

private static void test3() throws InterruptedException {
    Exchanger exchanger = new Exchanger();

    Thread thread = new Thread(() -> {
        try {
            Object data = "-公众号Java技术栈AAA";
            System.out.println(Thread.currentThread().getName() + data);

            // 开始交换数据
            data = exchanger.exchange(data);
            System.out.println(Thread.currentThread().getName() + data);
        } catch (Exception e) {
            e.printStackTrace();
        }
    });

    thread.start();

    // 线程中断
    Thread.sleep(3000L);
    thread.interrupt();
}

主线程休眠 3 秒后,中断该线程。

输出结果:

 

 

输出结果 3 秒后,线程被中断了,抛出了中断异常,线程也停止阻塞,最后线程结束运行。

posted @   KLAPT  阅读(81)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示