2

在我的应用程序中,我使用的是第三方 API。这是一种立即返回的非阻塞方法。我有一组元素,我必须在这些元素上调用此方法。

现在,我的问题是我必须找到一种方法,直到所有方法执行完成并进行下一个操作。我该如何处理?我无法修改第三方 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
4

3 回答 3

8

您所要求的是不可能的……除非第三方 API包含一些允许您等到一个或多个调用methodA完成的方法。

可以?

编辑

正如 Kathy Stone 所指出的,另一种可能性是 API 可能有一个回调机制,即执行由methodA调用启动的工作的线程(在 API 后面)“回调”到您的代码。(API 中需要有一些其他方法允许您注册回调对象。)

还有其他可能性......(有些太可怕了)......但它们都需要 API 被设计为支持与methodA.

于 2010-04-12T12:23:13.213 回答
3

正如斯蒂芬指出的那样,如果您有某种方式知道该方法已完成,那么这是可能的。如果您对此有某种回调或侦听器,则可以使用计数信号量之类的东西:

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 提供什么机制来知道调用已完成,但这是可以使用的一种方法。

于 2010-04-12T12:42:19.597 回答
0

您如何确定methodA()通话已结束?

该方法是否返回任何句柄?或者该对象是否有任何属性要由methodA()调用设置?因此,收集它们并使用 sleep 循环并检查所有剩余的句柄或对象属性,如果完成,则从剩余的句柄或对象属性中删除。

等待代码看起来像:

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();
    }
  }
}
于 2010-04-12T12:48:45.487 回答