我想知道是否有人使用过java.util.concurrent.Exchanger类。根据java docs,可以使用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();
}
}
可以使用两个CountDownLatch完成相同的操作。一个用于写入Buffer,一个用于在所有读取器线程处理完记录后通知writer。所以我的问题是
答案 0 :(得分:0)
使用CountDownLatches,您必须在某处放置对缓冲区的引用,以便两个线程都可以访问它们(或者传递对构造函数的引用)。这增加了程序代码的大小。 然后,您必须为每个事务重新创建CountDownLatch。
其他方法是:
UPDT
Exchanger是一对大小为1的阻塞队列,单个操作exhange
相当于queue1.put(value); return queue2.take();
。因此,当它的使用是合理的时,唯一的情况是当你需要一对大小为1的阻塞队列时,总是同时调用put和get。这是一种罕见的情况,我无法看到它被包含在标准java库中的原因。
答案 1 :(得分:0)
CountDownLatch
是一种同步机制。您将实例初始化为固定计数值N,然后等待,直到其他一些线程将此计数器递减为0.它通常用于使线程等待其他N个不同的线程完成。但当然还有很多其他应用程序。
Exchanger
是一种沟通机制。它允许您将对象从线程T1传递到T2,同时将对象从T2传递回T1。交换是阻塞的,因此您也可以将其用作同步机制,但这不是它的意思。