Exchanger与CountDownLatch

时间:2015-06-15 17:38:03

标签: java multithreading concurrency java.util.concurrent

我想知道是否有人使用过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。所以我的问题是

  1. Exchanger的理想用途
  2. 与CountDownLatch相比,它有什么优缺点

2 个答案:

答案 0 :(得分:0)

使用CountDownLatches,您必须在某处放置对缓冲区的引用,以便两个线程都可以访问它们(或者传递对构造函数的引用)。这增加了程序代码的大小。 然后,您必须为每个事务重新创建CountDownLatch。

其他方法是:

  • 使用Semaphores对而不是CountDownLatches - 无需重新创建
  • 使用一对ArrayBlockingQueues - 无需重新创建,无需担心对bufferes的引用,以及比使用Exchanger时更好的并行性。

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。交换是阻塞的,因此您也可以将其用作同步机制,但这不是它的意思。