問:你知道 Java 的 Exchanger 嗎?簡單說說其特點及應用場景?
答:Exchanger 是 JDK 1.5 開始提供的一個用于兩個工作線程之間交換數(shù)據(jù)的封裝工具類,簡單說就是一個線程在完成一定的事務后想與另一個線程交換數(shù)據(jù),則第一個先拿出數(shù)據(jù)的線程會一直等待第二個線程,直到第二個線程拿著數(shù)據(jù)到來時才能彼此交換對應數(shù)據(jù)。其定義為 Exchanger<V> 泛型類型,其中 V 表示可交換的數(shù)據(jù)類型,對外提供的接口很簡單,具體如下:
Exchanger():無參構造方法。V exchange(V v):等待另一個線程到達此交換點(除非當前線程被中斷),然后將給定的對象傳送給該線程,并接收該線程的對象。V exchange(V v, long timeout, TimeUnit unit):等待另一個線程到達此交換點(除非當前線程被中斷或超出了指定的等待時間),然后將給定的對象傳送給該線程,并接收該線程的對象。
可以看出,當一個線程到達 exchange 調用點時,如果其他線程此前已經調用了此方法,則其他線程會被調度喚醒并與之進行對象交換,然后各自返回;如果其他線程還沒到達交換點,則當前線程會被掛起,直至其他線程到達才會完成交換并正常返回,或者當前線程被中斷或超時返回。
public class Test {
static class Producer extends Thread {
private Exchanger<Integer> exchanger;
private static int data = 0;
Producer(String name, Exchanger<Integer> exchanger) {
super("Producer-" + name);
this.exchanger = exchanger;
}
@Override
public void run() {
for (int i=1; i<5; i++) {
try {
TimeUnit.SECONDS.sleep(1);
data = i;
System.out.println(getName()+" 交換前:" + data);
data = exchanger.exchange(data);
System.out.println(getName()+" 交換后:" + data);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
static class Consumer extends Thread {
private Exchanger<Integer> exchanger;
private static int data = 0;
Consumer(String name, Exchanger<Integer> exchanger) {
super("Consumer-" + name);
this.exchanger = exchanger;
}
@Override
public void run() {
while (true) {
data = 0;
System.out.println(getName()+" 交換前:" + data);
try {
TimeUnit.SECONDS.sleep(1);
data = exchanger.exchange(data);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(getName()+" 交換后:" + data);
}
}
}
public static void main(String[] args) throws InterruptedException {
Exchanger<Integer> exchanger = new Exchanger<Integer>();
new Producer("", exchanger).start();
new Consumer("", exchanger).start();
TimeUnit.SECONDS.sleep(7);
System.exit(-1);
}
}
可以看到,其結果可能如下:
Consumer- 交換前:0
Producer- 交換前:1
Consumer- 交換后:1
Consumer- 交換前:0
Producer- 交換后:0
Producer- 交換前:2
Producer- 交換后:0
Consumer- 交換后:2
Consumer- 交換前:0
Producer- 交換前:3
Producer- 交換后:0
Consumer- 交換后:3
Consumer- 交換前:0
Producer- 交換前:4
Producer- 交換后:0
Consumer- 交換后:4
Consumer- 交換前:0
可以看到,如上就是一種典型的使用場景,簡單理解這東西就是一個并發(fā)協(xié)作的工具類而已。