В некотором унаследованном коде, который я унаследовал, есть фрагмент, который выглядит примерно так:
List<Callable<String>> callableStrings = Arrays.asList("one", "two", "three").stream()
.map(s -> (Callable<String>) () -> s)
.collect(Collectors.toList());
List<String> results =
someExecutorService.invokeAll(callableStrings).stream()
.map(
future -> {
try {
return future.get();
} catch (ExecutionException | InterruptedException e) {
LOG.info("Unexpected Exception encountered while fetching result", e);
return null;
}
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
Вместо Callable<String>
я действительно имею дело с более сложными вычислениями. Сонар выдвигает на первый план catch (ExecutionException | InterruptedException e)
как проблему, предлагая всегда повторять InterruptedException
. https://rules.sonarsource.com/java/tag/multi-threading/RSPEC-2142
Цель этого кода, похоже, состоит в том, чтобы отфильтровать любые тяжелые вычисления, в которых возникла проблема, и вернуть только те, которые были выполнены успешно. Для контекста этот код вызывается в результате HTTP-запроса, который обрабатывает мое приложение. Если InterruptedException
разрешено распространяться до самого верха, тогда клиент получит ответ об ошибке, а не увидит список успешных результатов.
Существует много разных видов информации для быть найденным при работе с InterruptedException
из Future#get
. Большинство из тех, которые кажутся очень ясными и советами solid, это те, которые имеют дело с ситуацией, когда вы реализовали что-то вроде Runnable
и вызываете Future#get
из этого класса.
Этот ответ , { ссылка }, предполагает, что, если я вижу InterruptedException
, добавленный в приведенном выше коде, это указывает на то, что поток, обрабатывающий HTTP-запрос, был прерван, а не тот, на котором выполняется Future. Это правильно?
Мои вопросы:
- Должен ли я быть обеспокоен предупреждением сонара и, если да, какие плохие вещи произойдут в результате сохранения кода таким, какой он есть? такое?
- Как реорганизовать код для улучшения?