2010-04-12 150 views
2

在我的應用程序中,我使用的是第三方API。這是一個立即返回的非阻塞方法。我有一個元素集合,我必須調用這個方法。Java - 處理非阻塞呼叫

現在,我的問題是,我必須找到一種方法,直到所有的方法執行完成並執行我的下一個操作。我該如何處理?我無法修改第三方API。

總之它看起來像這樣

for(Object object: objects){ 
methodA(object); //this is a non-blocking call and returns immediately 
} 
// here I want to do my next task only after all the methodA calls completed execution 
+0

哪些第三方API您使用的? – 2010-04-12 12:22:40

+0

需要說明的是,當您引用「方法執行」時:是指您要等到methodA()完成,或者直到包含for循環的方法完成爲止? – Pops 2010-04-12 12:39:40

+0

@我的意思是我想等methodA()完成 – 2010-04-12 12:59:00

回答

8

你所要求的是不可能的...除非第三方API 包括一些方法,可以讓你等到一個或多個呼叫methodA已完成。

是嗎?

編輯

凱西斯通指出,另一種可能是空氣污染指數可能有一個回調機制,從而線程(API後面),該做由methodA通話開始的工作「回撥」到你的代碼。 (在API中需要一些其他方法,允許您註冊回調對象。)

還有其他可能性以及...(有些太可怕了)...但它們都包含API爲設計爲以支持與methodA開始的任務結束同步。

+1

或者至少在每次調用完成時給出回調。 – 2010-04-12 12:37:03

+0

它沒有任何回調或任何其他api獲得完成的詳細信息..我想我在這裏.. – 2010-04-12 13:03:04

+1

@sarav - 是的,這聽起來像你* *卡住...除非你有一些方法來獲得不可更改的API已更改。 – 2010-04-12 13:29:02

3

正如Stephen指出的那樣,如果您有某種方式知道該方法已經完成,如果你有某種回調或監聽器此,你可以使用像一個計數信號:

final Semaphore block = new Semaphore(); 

//HERE SOMETHING APPROPRIATE TO YOUR API 
myAPI.registerListener(new APIListener(){ 
    public void methodADone(){ 
    block.release(); 
    } 
}); 

int permits = 0; 
for(Object object: objects){ 
methodA(object); //this is a non-blocking call and returns immediately 
permits++; 
} 
block.acquire(permits); 

當然,你將需要額外的檢查,以確保您釋放許可證正確的對象集合,取決於如何你的代碼是線程化的,API提供了什麼機制來了解這個調用已經完成,但這是一種可以使用的方法。

+1

或者使用爲此模式設計的CountDownLatch。 – 2010-04-12 13:07:19

0

你如何決定一個methodA()電話已完成?

該方法是否返回任何句柄?或者該對象有任何屬性可由methodA()調用設置?因此,收集他們做一個睡眠循環,並檢查所有剩餘的句柄或對象屬性,每個從其餘的如果完成刪除。

等待的代碼卡恩樣子:

while(!remaining.isEmpty()) { 
    try { 
    Thread.sleep(100); 
    } catch (InterruptedException e) { 
    continue; 
    } 
    Iterator<HandleOrObjectWithProperty> i = remaining.iterator(); 
    while (i.hasNext()) { 
    HandleOrObjectWithProperty result = i.next(); 
    if (result.handleHasFinishedOrPropertyIsSet()) { 
     i.remove(); 
    } 
    } 
}