java多线程-Thread两个线程交换数据Exchanger
2017-04-25 10:27
776 查看
背景 继续讲解关于多线程的两个或双数个的数据交换,使用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();
}
}
运行结果如下
很明显吧,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类,接收到了传出类的数据。
二、使用CountDownLatchpublic 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();
}
}
publ
a264
ic 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,则继续执行下面代码。活学活用之前学习的东西
。其实使用cyclibarier也是可以做到这个效果的,还记的吗?只要把接收类也变为线程类就可以了。然后在new的时候,添加执行类。就Ok了。可以参考之前博文
详细说明 先来一个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();
}
}
运行结果如下
很明显吧,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类,接收到了传出类的数据。
二、使用CountDownLatchpublic 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();
}
}
publ
a264
ic 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,则继续执行下面代码。活学活用之前学习的东西
。其实使用cyclibarier也是可以做到这个效果的,还记的吗?只要把接收类也变为线程类就可以了。然后在new的时候,添加执行类。就Ok了。可以参考之前博文
相关文章推荐
- 多线程 : 使用 Exchanger 两个线程间交换数据(一手交钱一手交货)
- Exchanger——Java两个线程间交换数据的工具类
- java学习——使用Exchanger实现两个线程间的数据交换
- Java多线程与并发库高级应用之线程数据交换Exchanger
- 13____java线程同步工具类之线程数据交换(Exchanger)
- Java核心知识点学习----多线程 倒计时记数器CountDownLatch和数据交换的Exchanger
- java 多线程-实例数据交换器 Exchanger
- Java多线程编程之使用Exchanger数据交换实例
- Exchanger两个线程之间的数据交换
- java的Exchanger 两个线程可以交换对象Demo
- Java并发工具类之线程间数据交换工具Exchanger
- java线程研究---(7)Thread同步:多线程数据共用会产生问题
- Java线程总结(十):并发包------两个线程交换数据Exchanger
- Java线程:线程的同步与锁 一、同步问题提出 线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏。 例如:两个线程ThreadA、ThreadB都操作同一个对象Foo对
- Java Exchanger(两线程交换数据)
- 多线程编程13-----Exchanger同步工具类实现两线程数据交换
- Exchanger: 两个线程 间 交换 数据
- java 多线程-实例数据交换器 Exchanger
- java 多线程-实例数据交换器 Exchanger
- java 线程间交换数据的Exchanger