2015-06-15 21 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。交換被阻塞,因此您可以將其用作同步機制,但這不是它的意思。

相關問題