Reputation: 4747
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
Upvotes: 2
Views: 1326
Reputation: 20594
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();
}
}
}
Upvotes: 0
Reputation: 718798
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
.
Upvotes: 8
Reputation: 8222
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.
Upvotes: 3