FutureTask и неблокирующая проверка завершения
Как известно, метод get у фьючера приводит к блокировке текущего потока. Требуется получить результат без блокировки. Вариант с методами isDone/isCancelled и с последующим вызовом get приводит к эксепшену:
java.util.concurrent.ExecutionException: java.lang.IndexOutOfBoundsException at java.util.concurrent.FutureTask.report(FutureTask.java:122) at java.util.concurrent.FutureTask.get(FutureTask.java:188)
Сам код большой, поэтому приведу только вариант, где эксепшен воспроизводится (2-й while для воспроизведения ошибки):
ExecutorService executor = Executors.newFixedThreadPool(threadsNum);
List<Future<ResultWrapper>> futures = new LinkedList<Future<ResultWrapper>>();
class DownloadCallable implements Callable<ResultWrapper> {
@Override
public ResultWrapper call() {
...
}
...
dc = new DownloadCallable();
futures.add(executor.submit(dc));
...
final Iterator<Future<ResultWrapper>> it = futures.iterator();
try {
while (it.hasNext()) {
final Future<ResultWrapper> fut = it.next();
while (!(fut.isDone() || fut.isCancelled())) {
Thread.sleep(DATA_TIMEOUT);
}
Exception--> ResultWrapper res = fut.get();
if (res != null) {
results.add(res);
}
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
Если 2-й while убрать, то код отрабатывает нормально.
Почему так происходит? И как лучше реализовать неблокирующую проверку окончания работы callable потоков?