2015-06-15 22 views
0

我想知道是否有人使用java.util.concurrent.Exchanger类。根据java文档,交换器可用于共享一对线程之间的一些数据。以下示例是读取和写入数据以及线程间交互的典型用例。Exchanger Vs CountDownLatch

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也可以做同样的事情。一个用于写入缓冲区,一个用于在所有读取器线程处理完记录后通知编写器。所以我的问题是

  1. 什么是交换
  2. 理想的使用
  3. 它有哪些优点和缺点在说的CountDownLatch
+0

据我所知,你在上面得到的是'发生之前'关系的保证,即线程A对交换对象做的所有事情都将被线程B看到,反之亦然。顾名思义,它在线程之间交换对象,在一次调用中处理两个方向。它代表了比倒计时锁存器更专业但更高层次的操作。 – biziclop

+0

谢谢@biziclop。我想我能从中得到的是虽然同样的事情可以通过锁存器或信号量来实现,但是Exhanger对于这种工作是特定的,只要在读写器线程之间共享数据容器不是一个大问题。 – Tatha

+0

@Taffa这是我的至少承诺,但作为一个声明,我不得不说,我从来没有在愤怒中使用过“交换器”。可能很容易出现一些我忽略的重要细节。 – biziclop

回答

0

随着CountDownLatches,你必须从某个地方放置到缓冲器的引用,使它们可以被两个线程访问(或传递对构造函数的引用)。这增加了程序代码的大小。 然后,您必须为每个事务重新创建CountDownLatch。

其他方法是:

  • 使用对信号灯代替CountDownLatches的 - 不用重新ArrayBlockingQueues的
  • 使用对 - 不用重新创建,不用担心会bufferes参考,并更好并行度比使用Exchanger时要高。

UPDT 器是一对阻挡大小各1个的队列,用单一的操作exhange这相当于queue1.put(value); return queue2.take();的。所以唯一的情况是它的使用是合理的,当你需要一对大小为1的阻塞队列并且总是调用put并同时获取。这是一种罕见的情况,我看不到它被包含在标准java库中的原因。

+0

感谢@Alexei的建议。由于这种典型的用例可以通过很多方式实现,所以我想知道Exchanger是否比大多数其他解决方案更好? – Tatha

+3

@Tatha不要低估简单的价值。交换器非常简单易用。缺点是它解决了一个非常特殊的问题。 – biziclop

0

CountDownLatch是一种同步机制。您将一个实例初始化为一个固定的计数值N,然后等待,直到其他线程将此计数器递减为0.它经常用于使线程等待其他N个不同的线程完成。但当然还有很多其他应用程序。

Exchanger是一种沟通机制。它可以让你从线程T1到T2传递一个对象,同时从T2传递一个对象到T1。交换被阻塞,因此您可以将其用作同步机制,但这不是它的意思。

相关问题