Exchanger<V>,java.util.concurrent包下, 用于实现两个人之间的数据交换,每个人在完成一定的事务后想与对方交换数据,第一个先拿出数据的人将一直等待第二个人拿着数据到来时,才能彼此交换数据,V
- 可以交换的对象类型。
构造方法
public Exchanger()创建一个新的 Exchanger。
方法摘要
V exchange(V x)
等待另一个线程到达此交换点(除非当前线程被中断),然后将给定的对象传送给该线程,并接收该线程的对象。
V exchange(V x, long timeout, TimeUnit unit)
等待另一个线程到达此交换点(除非当前线程被中断,或者超出了指定的等待时间),然后将给定的对象传送给该线程,同时接收该线程的对象。
如下代码中使用Exchanger交换value的值:
/**
* Huisou.com Inc.
* Copyright (c) 2011-2012 All Rights Reserved.
*/
package thread;
import java.util.concurrent.Exchanger;
/**
* @description
*
* @author chenzehe
* @email hljuczh@163.com
* @create 2013-1-11 下午04:52:41
*/
public class ExchangerTest {
public static void main(String[] args) {
Exchanger<String> exchanger = new Exchanger<String>();
new Thread(new ExchangerThread("A", exchanger)).start();
new Thread(new ExchangerThread("B", exchanger)).start();
}
}
class ExchangerThread implements Runnable {
String value;
Exchanger<String> exchanger;
public ExchangerThread(String value, Exchanger<String> exchanger) {
this.value = value;
this.exchanger = exchanger;
}
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " before exchange:value-" + value);
Thread.sleep(3000);
value = exchanger.exchange(value);
System.out.println(Thread.currentThread().getName() + " after exchange:value-" + value);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Thread-0 before exchange:value-A
Thread-1 before exchange:value-B
Thread-1 after exchange:value-A
Thread-0 after exchange:value-B
下面代码中,该类使用 Exchanger
在线程间交换缓冲区,因此,在需要时,填充缓冲区的线程获取一个新腾空的缓冲区,并将填满的缓冲区传递给腾空缓冲区的线程:
class FillAndEmpty {
Exchanger<DataBuffer> exchanger = new Exchanger<DataBuffer>();
DataBuffer initialEmptyBuffer = ... a made-up type
DataBuffer initialFullBuffer = ...
class FillingLoop implements Runnable {
public void run() {
DataBuffer currentBuffer = initialEmptyBuffer;
try {
while (currentBuffer != null) {
addToBuffer(currentBuffer);
if (currentBuffer.isFull())
currentBuffer = exchanger.exchange(currentBuffer);
}
} catch (InterruptedException ex) { ... handle ... }
}
}
class EmptyingLoop implements Runnable {
public void run() {
DataBuffer currentBuffer = initialFullBuffer;
try {
while (currentBuffer != null) {
takeFromBuffer(currentBuffer);
if (currentBuffer.isEmpty())
currentBuffer = exchanger.exchange(currentBuffer);
}
} catch (InterruptedException ex) { ... handle ...}
}
}
void start() {
new Thread(new FillingLoop()).start();
new Thread(new EmptyingLoop()).start();
}
}