Exchanger简介
Exchanger通常用来解决以下类似场景的问题,如下:两个线程间需要交换数据的问题,在多线程编程中,经常会有这样的场景:两个线程各自持有一些数据,并且需要在某个点上交换这些数据,Exchanger类提供了一个简单、高效的机制来实现这种数据交换。
Exchanger类充当了一个数据交换的“中间站”,两个线程在需要交换数据时,会分别调用Exchanger的exchange()方法,并在该方法上阻塞等待,当两个线程都到达这个“中间站”时,Exchanger会负责将它们手中的数据进行交换,然后两个线程就可以继续各自的任务了。
好处是,它不需要额外的锁或同步机制来保证数据交换的正确性,Exchanger类内部已经实现了这些同步机制,使用起来非常简单方便,而且,由于Exchanger类是基于Java的并发包java.util.concurrent实现的,因此它具有很高的性能和可扩展性。
public class ExchangerTest {
public static void main(String[] args) {
Exchanger<String> exchanger = new Exchanger<>();
new Thread(new Producer(exchanger)).start();
new Thread(new Consumer(exchanger)).start();
}
}
class Producer implements Runnable {
Exchanger<String> exchanger;
public Producer(Exchanger<String> exchanger) {
this.exchanger = exchanger;
}
@Override
public void run() {
try {
String producedData = "Data from Thread 1";
String consumerData = exchanger.exchange(producedData);
System.out.println("Thread 1 received: " + consumerData);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Consumer implements Runnable {
Exchanger<String> exchanger;
public Consumer(Exchanger<String> exchanger) {
this.exchanger = exchanger;
}
@Override
public void run() {
try {
// 为了让示例更清晰,让第二个线程稍微延迟一会儿,确保第一个线程先到达交换点
String producedData = "Data from Thread 2";
Thread.sleep(100);
String producerData = exchanger.exchange(producedData);
System.out.println("Thread 2 received: " + producerData);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}