2010-04-12 120 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(); 
    } 
    } 
}