views:

198

answers:

3

In my application I am using a third-party 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.

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
+8  A: 

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.

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. (There would need to be some other method in the API that allows you to register the callback object.)

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.

Stephen C
Or at least gives a callback when each call is completed.
Kathy Van Stone
it doesnt has any callback or any other api to get completion details.. i guess i'm struck here..
sarav
@sarav - Yup, it sounds like you *are* stuck ... unless you have some way to get the unchangeable API changed.
Stephen C
+3  A: 

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.

M. Jessup
Or use a CountDownLatch, which is designed for this pattern.
Alex Feinman
A: 

How do you dertermine a methodA() call has finished?

Does the method return any handle? Or do the object has any property to be set by the methodA() call? 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();
    }
  }
}
Arne Burmeister