【Java并发编程】02.Exchanger的使用

Java并发编程是我刚刚开设的一个专栏,记录我学习Java并发编程的笔记、思考,希望大家共同进步。专栏地址:http://blog.csdn.net/column/details/14538.html,欢迎关注。

本专栏所有的代码我都会上传到GitHub。
GitHub地址是:https://github.com/mrbcy/JavaConcurrentLearn

本来过几天我才会有时间再看并发编程的,但是今天收到通知说专栏申请通过了,那没啥好说的,今天一定要更新一篇。

这次我们关注的类是Exchanger,它主要用于两个线程之间传递数据,比生产者/消费者模型中使用的wait/notify更加的方便。这篇博客会给出Exchanger类在两个线程之间传递任意类型数据的示例。

Exchanger类的结构和使用非常简单,主要就是学习exchange()方法的使用。

方法exchange()的阻塞特性

类Exchanger中的exchange()方法具有阻塞特性,调用该方法后会等待其他线程来取得数据,如果没有其他线程取得数据,会一直阻塞等待。

示例代码如下:

ThreadA.java

package tech.mrbcy.javaconcurrentlearn.e02_1;

import java.util.concurrent.Exchanger;

public class ThreadA extends Thread{
    private Exchanger<String> exchanger;

    public ThreadA(Exchanger<String> exchanger) {
        super();
        this.exchanger = exchanger;
    }

    @Override
    public void run() {
        super.run();

        try {
            System.out.println("在线程A中得到线程B中的值:" + exchanger.exchange("AAAAA"));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


}

Run.java

package tech.mrbcy.javaconcurrentlearn.e02_1;

import java.util.concurrent.Exchanger;

public class Run {
    public static void main(String[] args) {
        Exchanger<String> exchanger = new Exchanger<String>();

        ThreadA a = new ThreadA(exchanger);
        a.start();
        System.out.println("main end!");
    }
}

运行后,ThreadA会阻塞,效果如图所示:

使用exchange()方法传递值

在上面的例子中再添加一个类,ThreadB

ThreadB.java

package tech.mrbcy.javaconcurrentlearn.e02_2;

import java.util.concurrent.Exchanger;

public class ThreadB extends Thread{
    private Exchanger<String> exchanger;

    public ThreadB(Exchanger<String> exchanger) {
        super();
        this.exchanger = exchanger;
    }

    @Override
    public void run() {
        super.run();

        try {
            System.out.println("在线程B中得到线程A中的值:" + exchanger.exchange("BBBBB"));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


}

然后略微修改一下Run

package tech.mrbcy.javaconcurrentlearn.e02_2;

import java.util.concurrent.Exchanger;

public class Run {
    public static void main(String[] args) {
        Exchanger<String> exchanger = new Exchanger<String>();

        ThreadA a = new ThreadA(exchanger);
        ThreadB b = new ThreadB(exchanger);
        a.start();
        b.start();
    }
}

运行一下就可以看到ThreadA和ThreadB分别拿到了对方传过来的值。

运行结果:

在线程B中得到线程A中的值:AAAAA
在线程A中得到线程B中的值:BBBBB

exchange()方法的超时

exchanger()方法的调用方也可以指定在多长时间内没有其他线程获取数据,则不再等待,抛出超时异常。

再把ThreadA修改一下,然后把Run再改回最开始的样子。

ThreadA.java

package tech.mrbcy.javaconcurrentlearn.e02_3;

import java.util.concurrent.Exchanger;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class ThreadA extends Thread{
    private Exchanger<String> exchanger;

    public ThreadA(Exchanger<String> exchanger) {
        super();
        this.exchanger = exchanger;
    }

    @Override
    public void run() {
        super.run();

        try {
            System.out.println("在线程A中得到线程B中的值:" + exchanger.exchange("AAAAA", 5, TimeUnit.SECONDS));
            System.out.println("A end!");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        }
    }


}

Run.java

package tech.mrbcy.javaconcurrentlearn.e02_3;

import java.util.concurrent.Exchanger;

public class Run {
    public static void main(String[] args) {
        Exchanger<String> exchanger = new Exchanger<String>();

        ThreadA a = new ThreadA(exchanger);
        a.start();
        System.out.println("main end!");
    }
}

运行结果如下:

main end!
java.util.concurrent.TimeoutException
    at java.util.concurrent.Exchanger.exchange(Exchanger.java:683)
    at tech.mrbcy.javaconcurrentlearn.e02_3.ThreadA.run(ThreadA.java:20)

总结

使用Exchanger类可以方便的在线程间传递数据,而且数据的类型没有任何限制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值