java.util.concurrent包下Exchanger<T>类可以实现两个线程之间的数据交换,其中参数T是泛型,表示交换的对象类型。
Exchanger<T>只有一个无参构造器,Exchanger()。
有两个重载方法exchange(V x)和exchange(V x, long timeout, Timeunit, unit)。作用是等待另一个线程达到此交换点(除非当前线程被中断),然后将给定对象传送给该线程,并接收该线程持有的对象;如果另一个线程已经在交换点等待,则出于线程调度目的,继续执行此线程,并接收当前线程传入的对象,当前线程立即返回,接收其他线程传递的交换对象。exchange(V x, long timeout, Timeunit, unit)可以设置等待时间,如果超出等待时间则抛出TimeoutException异常。
下面我们举个例子来体会Exchanger的用法
数千年前的远古时代,在还没有“钱”的概念的时候,老祖宗们进行商品交换的方式是“以物易物”,虽然物物价值并不一定相等,但是这在当时也不失为一种好的方法。下面我们就通过Exchanger来实现“物物交换”
package com.gk.thread.exchanger;
import java.util.concurrent.Exchanger;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class ExchangerDemo {
public static void main(String[] args) {
Exchanger<Animal> exch = new Exchanger<Animal>();
new Thread() {
@Override
public void run() {
this.setName("zhangSan");
if (! this.isInterrupted()) {
Animal animal = new Animal("牛", 1);
System.out.println(this.getName() + "交换前拥有 : " + animal);
try {
animal = exch.exchange(animal, 3L, TimeUnit.SECONDS); // 进行交换,等待时间为3秒
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (TimeoutException e) {
System.out.println("等待超时...");
System.exit(0); // 如果不强制退出的话,对方线程就会无限等待下去
}
System.out.println(this.getName() + "交换后拥有 : " + animal);
}
}
}.start();
/
new Thread() {
@Override
public void run() {
this.setName("liSi");
if (! this.isInterrupted()) {
Animal animal = new Animal("羊", 2);
System.out.println(this.getName() + "交换前拥有 : " + animal);
try {
Thread.sleep(1000 * 2); // 通过设置休眠时间来改变超时的状态
animal = exch.exchange(animal); // 进行交换
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(this.getName() + "交换后拥有 : " + animal);
}
}
}.start();
}
}
package com.gk.thread.exchanger;
public class Animal {
private String name;
private int number;
public Animal(String name, int number) {
this.name = name;
this.number = number;
}
@Override
public String toString() {
return name + ", " + number + "只...";
}
}
从运行结果可以看出,在交换之前,zhangSan拥有的是1只牛,liSi拥有的是2只羊,交换之后,zhangSan拥有的是2只羊,liSi拥有的是1只牛。从而简单实现了两个线程之间的数据交换。
有兴趣的话,也可以基于上面代码,测试中断和超时时程序运行的效果。