2012-07-03 48 views
2

在我的程序中,我基本上試圖連接到發佈者並獲取數據。基本功能是有在這些步驟以單線程方式包裝回調函數

  1. 我讓我做對數據的請求,用戶名和密碼等
  2. 出版商的連接。方法退出
  3. 廣告發布商的API給了我一個回調的方法onDataUpdate(Object theUpdate)

從那裏,我可以打印數據,或將其寫入到數據庫或任何我需要做的。這一切都有效。

我的問題是,我現在想以這樣的方式包裝功能,即調用程序可以說請求數據並儘快收到它。意思是說,我想讓我的暴露方法看起來像

public Object getData() { 
    subscribeForData(); 
    // somehow wait 
    return theUpdate;  
} 

我該如何做到這一點?有什麼方法可以使用線程在我收到更新時等待/通知?我是一個新的stackoverflow和多線程編程,所以任何幫助和示例代碼將不勝感激!提前致謝。

回答

1

在這種情況下,我寧願用CountDownLatch,在那裏我會初始化我lathch以計數1,一旦我對latch認購發行人我會打電話給await(),當我得到的回調,我會countdownlatch

+0

來自CountDownLatch的javadoc:'一種同步協助,它允許一個或多個線程等待,直到在其他線程中執行的一組操作完成爲止。 – Wolfgang

+0

你有這樣的例子嗎?我似乎無法得到它的工作。我在我的調用類中創建了一個新的CountDownLatch,並將它傳遞給實際接收更新的類。所以他們都提到了同樣的鎖定。在我的onDataUpdate方法中,我調用latch上的countDown,但似乎沒有通知其他正在無限期等待的類。思考? – Korra

+0

@Korra我建議你用你的代碼編輯問題。 –

0

使用SynchronousQueue。在getData中創建它,在回調方法中調用put(),然後在getData()的末尾的原始線程中調用take()。

0

我不能完全肯定你的問題,但我給它一個鏡頭 - 希望它幫助:)

你可以使用Java中的一個的BlockingQueue用於此目的(生產者消費者信息) - 如果你寫當回調被調用時 - 從另一個線程到隊列,您可以從隊列中讀取。阻塞隊列是線程安全的(但可能不符合您的要求)。

如果您只有一個線程寫入集合,也許還有多個讀取器(甚至只是讀取器),您還可以查看讀寫鎖定。

你也可以看看觀察者模式 - 以供參考:http://www.vogella.com/articles/DesignPatternObserver/article.html

如果沒有這些工作,我們可以考慮使用從VM內消息服務器進行隊列/主題如ZeroMQ/ActiveMQ的或可能像Redis/HazelCast。

希望它可以幫助和好運

0

轉換一個異步調用一個同步是一項有趣的工作,我經常用它在採訪中(反之,包裹在異步同步調用)。

因此,有一個requestData方法會立即返回,並(或別的東西)後會調用onDataUpdate不同的線程。您想要創建一個新方法,例如requestDataSynchronous,它不要求呼叫方使用回叫,而是使用阻止,直到數據可用並將其返回給呼叫方。

所以你需要什麼requestDataSynchronous做的是:

  1. 呼叫requestData
  2. 等到onDataUpdate叫(在不同的線程)
  3. 獲取數據onDataUpdate收到
  4. 它返回到來電者

以上,#2和#3必須通過某種線程間通信模式來完成。您可以使用wait/notifiy,但使用BlockingQueue可能會更簡單。一旦有數據,onDataUpdate就會向其寫入數據,並且requestDataSynchronous會從中讀取數據,並在讀取時阻止,直到onDataUpdate寫入數據。

使用ExecutorService可能會使這更容易,但知道發生了什麼會很有用。

+0

謝謝!我現在使用CountDownLatch,因爲它看起來更簡單。使用BlockingQueue有沒有什麼好處,我可能沒有想到?你聽起來像一個艱難的採訪者:-) – Korra