线程之间如何交换数据?
JUC中的Exchanger
java.util.concurrent.Exchanger
实现了两个线程之间交换数据
交换器类Exchanger
方法 | 说明 |
---|---|
V exchange(V x) | 交换数据,没有线程交换就一直阻塞 |
V exchange(V x, long timeout, TimeUnit unit) | 在指定时间内没有线程交换,就抛出超时异常 |
简单测试exchange(V x)
public class Test1 {
//创建交换器类的实例
static Exchanger exchanger = new Exchanger();
public static void main(String[] args) {
new Thread(() -> {
Object data = "AAA";
System.out.println(Thread.currentThread().getName() + ":" + data);
//交换数据
try {
data = exchanger.exchange(data);
System.out.println(Thread.currentThread().getName() + ":" + data);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}).start();
new Thread(() -> {
Object data = "BBB";
System.out.println(Thread.currentThread().getName() + ":" + data);
//交换数据
try {
data = exchanger.exchange(data);
System.out.println(Thread.currentThread().getName() + ":" + data);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}).start();
}
}
超时测试 exchange(V x, long timeout, TimeUnit unit)
public class Test2 {
static Exchanger exchanger = new Exchanger();
public static void main(String[] args) {
new Thread(() -> {
Object data = "AAA";
System.out.println(Thread.currentThread().getName() + ":" + data);
//交换数据
try {
// 交换的数据,超时时间,时间单位
data = exchanger.exchange(data,3000, TimeUnit.MICROSECONDS);
System.out.println(Thread.currentThread().getName() + ":" + data);
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (TimeoutException e) {
throw new RuntimeException(e);
}
}).start();
}
}
没有其他线程与之进行数据交换,超时后抛出异常
中断测试
一个线程开始交换数据后,如果没有其他线程和它交换,就会一直阻塞,直到有线程交换、中断、超时等情况出现。
阻塞…
中断
开启线程数据交换后,中断线程
public class Test3 {
static Exchanger exchanger = new Exchanger();
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
Object data = "AAA";
System.out.println(Thread.currentThread().getName() + ":" + data);
//交换数据
try {
data = exchanger.exchange(data);
System.out.println(Thread.currentThread().getName() + ":" + data);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
t.start();
Thread.sleep(3000);
t.interrupt();//线程中断
}
}
中断线程后,线程停止阻塞,结束运行
理解Exchanger两两交换数据
十个线程之间是如何交换数据的?
public class Test4 {
static Exchanger exchanger = new Exchanger();
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 10; i++) {
Integer data = i;
new Thread(() -> {
//交换数据
try {
Object res = exchanger.exchange(data);
System.out.println(Thread.currentThread().getName() + ":" + res);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}).start();
}
}
}
可以看到10个线程两两之间交换了数据
如果9个线程之间交换数据,会发生什么捏?
9个线程之间交换数据,有四对线程互换数据了,最后一个线程不参与交换