Java - Обработка неблокирующих вызовов - PullRequest
2 голосов
/ 12 апреля 2010

В моем приложении я использую сторонний 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 ]

8 голосов
/ 12 апреля 2010

То, что вы просите, невозможно ... если только сторонний API также не включает в себя какой-либо метод, который позволяет вам дождаться завершения одного или нескольких вызовов methodA.

Есть ли это?

РЕДАКТИРОВАТЬ

Как отмечает Кэти Стоун, другая возможность состоит в том, что в API может быть механизм обратного вызова, посредством которого поток (за API), выполняющий работу, начатую вызовом methodA, «перезванивает» вашему коду. (В API должен быть какой-то другой метод, позволяющий зарегистрировать объект обратного вызова.)

Есть и другие возможности ... (некоторые слишком ужасны, чтобы упоминать) ... но все они влекут за собой API, разработанный для поддержки синхронизации с завершением задач, запущенных methodA.

3 голосов
/ 12 апреля 2010

Как заметил Стивен, это возможно, если у вас есть какой-то способ узнать, что метод завершен. Если у вас есть какой-то обратный вызов или слушатель для этого, вы можете использовать что-то вроде счетного семафора:

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 предоставляет, чтобы узнать, завершился ли вызов, но это один из подходов, использоваться.

0 голосов
/ 12 апреля 2010

Как вы определите, закончился ли вызов 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();
    }
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...