所以,我遇到了一个问题,由于InterruptedExceptions
处理不当,Sonar Qube正在标记我的代码.精确的Sonar Qube误差为java:S2142
,可在此处找到:https://github.com/joansmith/sonar-java/blob/master/java-checks/src/main/resources/org/sonar/l10n/java/rules/squid/S2142.html
我的代码如下-Sonar Qube将extractFutureIntoList()
中可能InterruptedExceptions
的处理标记为问题的根源:
@Service
@Log4j2
public class AsynchronousDataGrabber {
ExecutorService executorService = Executors.newFixedThreadPool(10);
public List<MyDataObject> getDataAsynchronously() {
Optional<Future<MyDataObject>> future01 = getDataFuture("01");
Optional<Future<MyDataObject>> future02 = getDataFuture("02");
Optional<Future<MyDataObject>> future03 = getDataFuture("03");
List<MyDataObject> list = new ArrayList();
extractFutureIntoList(future01, list);
extractFutureIntoList(future02, list);
extractFutureIntoList(future03, list);
return list;
}
private Optional<Future<MyDataObject>> getDataFuture(String key) {
try {
return Optional.of(executorService.submit(() -> getDataFromRemoteApi(key)));
} catch(Exception e) {
log.error("Exception", e);
return Optional.empty();
}
}
private void extractFutureIntoList(Optional<Future<MyDataObject>> future, List<MyDataObject> list) {
try {
if (future.isPresent()) {
// This is apparently where the `InterruptedException` can occur - Future.get()
list.add(future.get().get());
}
} catch (Exception e) {
// SonarQube is telling me that merely logging an `InterupptedException` is not enough
// Apparently, I must either rethrow the `InterruptedException`,
//or call `Thread.currentThread().interrupt()
log.error("Exception", e);
return;
}
}
}
声纳Qube建议我解决这个问题,要么重新抛出InterruptedException
,要么拨打Thread.currentThread().interrupt()
--每当Future.get()
被打断时.
我的问题是,我的应用程序的主线程正在调用getDataAsynchronously()
.如果对InterruptedException
的唯一可接受的响应是重新抛出它或中断当前线程,那么executorService's
个线程中的一个中断就会导致整个应用程序崩溃.这似乎是一个过度的响应,特别是考虑到由线程getDataFromRemoteApi()
运行的任务无论如何可能并不总是成功的.
有没有更好的方法来处理InterruptedException
-理想的是Sonar Qube可以接受的方法,但不涉及杀死试图调用Future.get()
的线程?
我试过记录InterruptedException
米(log.error("Exception", e);
米),我试图抓住InterruptedException
米(throw new RuntimeException(e);
米)并重新抛出--都没有安抚索纳尔·奎比.