Java-Обработка Неблокирующих Вызовов
В моем приложении я использую сторонний 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
3 ответа:
То, о чем вы просите, невозможно ... если только сторонний API также не содержит какой-либо метод, позволяющий дождаться завершения одного или нескольких вызовов
methodA
.Так ли это?
EDIT
Как отмечает Кэти Стоун, другая возможность заключается в том, что API может иметь механизм обратного вызова, при котором поток (за API), выполняющий работу, начатую вызовомmethodA
, "перезванивает" в ваш код. (Там должен быть какой-то другой метод в API, который позволяет зарегистрировать объект обратного вызова.)Есть и другие возможности ... (некоторые слишком ужасны, чтобы их упоминать)... но все они подразумевают, что APIразработан для поддержки синхронизации с окончанием задач, запущенных
methodA
.
Как заметил Стивен, это возможно, если у вас есть какой-то способ узнать, что метод завершен. Если у вас есть какой-то обратный вызов или прослушиватель для этого, вы можете использовать что-то вроде Счетного семафора:
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 предоставляет, чтобы знать, что вызов завершен, но это один из подходов, который может быть использован.
Как вы определение в
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(); } } }