Обработка тайм-аута FutureTask - PullRequest
2 голосов
/ 11 ноября 2008

Допустим, я делаю что-то в Java, например:


RemoteResponse response = null;
try {
   FutureTask task new FutureTask(....);
   executor.execute(task);
   response = task.get(1000, TimeUnits.MILLISECONDS);
}
catch( TimeoutException te ) {
   <b>
   .. should I do something special here? ...
   .. what happens to the return value of the task if task.get() throws an exception? ...
   .. is it ever garbage collected? ..
   </b>
}

Мой вопрос: что-то удерживает RemoteResponse в случае, когда выбрасывается TimeoutException? Будет ли это собирать мусор? Нужно ли вызывать метод cancel () для задачи, чтобы это произошло?

Ответы [ 2 ]

3 голосов
/ 11 ноября 2008

Изменить после того, как вопрос был пересмотрен:

response является ссылкой на RemoteResponse, за который task отвечает за распределение. Присвоение возвращаемого значения из метода не произойдет, если метод вызвал исключение, поэтому нет необходимости в специальной обработке response.

task не будет ссылаться, когда он выходит из области видимости, либо в результате обычного выполнения, либо в случае возникновения исключения.

Если ресурсы, выделенные task, хорошо инкапсулированы, т. Е. Нет внешних ссылок и освобождаются (close, release, что угодно), то утечки ресурсов не должно быть.

Нет необходимости вызывать метод отмены, если не существует общего ресурса, которым обладает task, или какого-либо другого расходного ресурса, который необходим остальной части приложения.

Я бы хотя бы зарегистрировал тот факт, что задача не была выполнена за отведенное время. Что еще вы делаете, зависит от требований вашего приложения.

Обратите внимание, что task будет продолжаться до завершения, независимо от вызова get.

1 голос
/ 16 сентября 2009

Я думаю, что способ взглянуть на проблему заключается в том, что вам нужно запросить ресурс за пределами FutureTask, так что, когда вы решите отменить его, вы можете принудительно восстановить ресурсы.

так:

Resource res = null;
try {
 resource = ResourceAquirer.claim()

 FutureTask<?> task = new FutureTask<?>(resource);
 executor.execute(task);   
 response = task.get(1000, TimeUnits.MILLISECONDS);
} catch (Exception e) {
  // logging
} finally {
 if (resource != null) {
   resource.release();
 }
}

Таким образом, вы можете быть уверены, что ресурс будет освобожден. Действительно разочаровывает, что все это не может быть инкапсулировано в будущей задаче, но я не могу найти доказательств того, что вызов отмены в будущей задаче обеспечит запуск блока finally внутри FutureTask. (Может быть, я задам это как другой вопрос)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...