简体   繁体   English

Java - 处理非阻塞调用

[英]Java - Handling Non-Blocking Calls

In my application I am using a third-party API. 在我的应用程序中,我使用的是第三方API。 It is a non-blocking method which returns immediately. 这是一种立即返回的非阻塞方法。 I have a collection of elements over which I have to invoke this method. 我有一个元素集合,我必须调用此方法。

Now, my problem is that I have to find a way till all the method execution gets completed and do my next operation. 现在,我的问题是我必须找到一种方法,直到所有方法执行完成并进行下一步操作。 How can I handle this? 我怎么处理这个? I cannot modify the third-party API. 我无法修改第三方API。

In short it looks like this 简而言之,它看起来像这样

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

What you are asking for is impossible ... unless the third party API also includes some method that allows you to wait until one or more calls to methodA have completed. 您要求的是不可能的......除非第三方API 包含一些方法,允许您等到对methodA一个或多个调用完成。

Does it? 可以?

EDIT 编辑

As Kathy Stone notes, another possibility is that the API might have a callback mechanism, whereby a thread (behind the API) that is doing the work started by the methodA call "calls back" to your code. 凯西斯通指出,另一种可能是空气污染指数可能有一个回调机制,从而线程(API后面)是做在开始工作methodA调用“回调”到你的代码。 (There would need to be some other method in the API that allows you to register the callback object.) (API中需要一些其他方法允许您注册回调对象。)

There are other possibilities as well ... (some too horrible to mention) ... but they all entail the API being designed to support synchronization with end of the tasks started by methodA . 还有其他可能性......(有些太可怕了)......但它们都需要API 设计为支持与methodA启动的任务结束同步。

As Stephen noted it is possible if you have some way of knowing that the method has completed. 斯蒂芬指出,如果你有办法知道该方法已经完成,那么这是可能的。 If you have some kind of callback or listener for this you could use something like a counting semaphore: 如果您有某种回调或监听器,您可以使用类似计数信号量的东西:

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);

Of course you would need extra checking to make sure you are releasing permits for the correct object collections, depending on how your code is threaded and what mechanism the API provides to know the call has completed, but this is one approach that could be used. 当然,您需要额外检查以确保您正在为正确的对象集合发布许可,具体取决于代码的线程化以及API提供哪些机制来了解调用已完成,但这是一种可以使用的方法。

How do you dertermine a methodA() call has finished? 你如何确定方法A methodA()调用已完成?

Does the method return any handle? 该方法是否返回任何句柄? Or do the object has any property to be set by the methodA() call? 或者该对象是否有通过methodA()调用设置的任何属性? So collect them an do a loop with sleep and check all remaining handles or object properties, each removed from the remaining if completed. 因此,在睡眠时收集它们并检查所有剩余的句柄或对象属性,如果已完成,则从剩余的句柄或对象属性中删除。

The waiting code cann look like: 等待代码看起来像:

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();
    }
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM