java多线程-Thread两个线程交换数据Exchanger

背景
继续讲解关于多线程的两个或双数个的数据交换,使用Exchanger类进行。那么除此之外再讲解下如何给线程里面传值,并且如何从一个已经结束的线程里面取值,传出来使用。把线程的一些常用的东西记录下。

详细说明

先来一个demo,对两个进程进行数据交换。Exchanger,这个类的名字也十分直接,不就是交换器吗。

/**
* 2017-4-21
* author:饶为
* Administrator
*/
package Thread;
import java.util.concurrent.Exchanger;

/**
* 2017-4-21
* author:饶为
* Administrator
*/
public class ExchangerTest {
public static void main(String[] args) {
final Exchanger<String> exchanger = new Exchanger<String>();

new Thread(){
public void run(){
String a = "第一个线程";
try {
a = exchanger.exchange(a);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread1"+a);
}
}.start();

new Thread(){
public void run(){
String a = "第二个线程";
try {
a = exchanger.exchange(a);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread2"+a);
}
}.start();
}
}

很直观,直接把两个线程数据调换过来了。可以根据运行结果,来进行查看。
那么这个类是可以运行在双数进程上,如果再添加一个进程,则第三个进程不运行。

那么我们可以实验下双数的运行结果,我添加四个进程。

/**
* 2017-4-21
* author:饶为
* Administrator
*/
package Thread;
import java.util.concurrent.Exchanger;

/**
* 2017-4-21
* author:饶为
* Administrator
*/
public class ExchangerTest {
public static void main(String[] args) {
final Exchanger<String> exchanger = new Exchanger<String>();

new Thread(){
public void run(){
String a = "第一个线程";
try {
a = exchanger.exchange(a);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread1"+a);
}
}.start();

new Thread(){
public void run(){
String a = "第二个线程";
try {
a = exchanger.exchange(a);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread2"+a);
}
}.start();

new Thread(){
public void run(){
String a = "第三个线程";
try {
a = exchanger.exchange(a);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread3"+a);
}
}.start();

new Thread(){
public void run(){
String a = "第四个线程";
try {
a = exchanger.exchange(a);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread4"+a);
}
}.start();
}
}

运行结果如下
java多线程-Thread两个线程交换数据Exchanger - 饶为 - 饶为先生的博客
 
很明显吧,1和2的数据交换了,3和4的交换了。那么大家可以自己尝试下单数个线程使用。

一个进程执行完后,把数据传值到另一个进程中

这个其实很简单,就是需要传出去的进程设置一个方法,得到想要的数据,当这个进程执行完后,去执行另一个进程。
这里我提供两个方法,一个是Join(),一个是CountDownLatch类。

一、使用join方法来实现执行完线程后,再去执行其他方法。代码如下
首先先弄一个传数据出去的类,称为 传出类
那传出类代码很简单,我贴下

/**
* 2017-4-21
* author:饶为
* Administrator
*/
package Thread;
/**
* 2017-4-21
* author:饶为
* Administrator
*/
public class Exchanger1 extends Thread {

String aString;

/* (non-Javadoc)
* @see java.lang.Thread#run()
*/
@Override
public void run() {
// TODO Auto-generated method stub
this.aString="我的线程1";

try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public String getS(){
return aString;
}
}

这里注意的就是getS这个方法,这个是用来传值的。
接下来是接收这个线程传值的方法。

ublic class ET {
public static void main(String[] args) throws InterruptedException {
exchanger.start();
countDownLatch.await();
Exchanger1 exchanger = new Exchanger1();
exchanger.start();
exchanger.join();

String a = exchanger.getS();
System.out.println(a);

}
}

讲讲这个join方法,这个其实是就是只有线程执行完后,才会运行下面的方法,它其实 join()方法的实现原理是不停检查join线程是否存活,如果join线程存活则让当前线程永远等待。直到join线程完成后,线程的this.notifyAll()方法会被调用。
那么运行结果,就是ET类,接收到了传出类的数据。

二、使用CountDownLatch

public class Exchanger1 extends Thread {

private CountDownLatch countDownLatch;
public Exchanger1(CountDownLatch countDownLatch){
this.countDownLatch = countDownLatch;
}
String aString;

/* (non-Javadoc)
* @see java.lang.Thread#run()
*/
@Override
public void run() {
// TODO Auto-generated method stub
this.aString="我的线程1";

try {
Thread.sleep(5000);
countDownLatch.countDown();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public String getS(){
return aString;
}
}


这个是传出类。CountDownLatch,我之前的博文中已经介绍了它的使用方法,就是当cdl减少为0的时候,才会继续执行下面的代码,否则会阻塞。那么接收类代码为

public class ET {
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(1);
Exchanger1 exchanger = new Exchanger1(countDownLatch);

exchanger.start();
countDownLatch.await();
String a = exchanger.getS();
System.out.println(a);
}
}

很明显,用await方法阻塞,当执行了countdown方法后,countdownlatch为0,则继续执行下面代码。活学活用之前学习的东西 java多线程-Thread两个线程交换数据Exchanger - 饶为 - 饶为先生的博客
其实使用cyclibarier也是可以做到这个效果的,还记的吗?只要把接收类也变为线程类就可以了。然后在new的时候,添加执行类。就Ok了。可以参考之前博文
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值