下面是我使用ExecutorService的代码实现
public void startDownloading(DownloadInfo downloadInfo) {
int messageSentToNextQueue = 0;
ExecutorService downloadExecutor = Executors.newSingleThreadExecutor();
try {
Callable<Integer> task = () -> {
return fileDownloader.downloadFromSourceLink(downloadInfo);
};
Future<Integer> future = downloadExecutor.submit(task);
try {
if (downloadInfo.getExtension().equals(ScraperConstant.ZIP_EXTENSION)) {
messageSentToNextQueue = future.get(11, TimeUnit.HOURS);
} else if (downloadInfo.getExtension().equals(ScraperConstant.HTML_EXTENSION)) {
messageSentToNextQueue = future.get(10, TimeUnit.MINUTES);
} else {
messageSentToNextQueue = future.get(30, TimeUnit.MINUTES);
}
} catch (Exception e) {
log.error(ex);
downloadExecutor.shutdownNow();
}
} catch (Exception ex) {
log.error(ex);
} finally {
if (!downloadExecutor.isShutdown()) {
downloadExecutor.shutdownNow();
}
}
}
现在,我在每个方法调用上使用SingleThreadExecutor创建ExecutorService,因为在超时的情况下,我可以关闭服务以释放所有底层资源并停止任何进一步的处理。
如果我使用ThreadPoolExecutor并在类级别初始化它并重用它,这肯定是一种更好的方法,但在这种情况下,如果超时发生,我必须关闭完整的ExecutorService以释放资源,这将导致其他线程在该ExecutorService下处理时也停止,我还必须在关闭后初始化ExecutorService。
如果有人提出更好的方法,那就太好了。
1条答案
按热度按时间bvjxkvbb1#
样式注解:
我不会在三个地方重复
messageSentToNextQueue = future.get(...)
调用。我也不会在startDownloading
函数中编码不同的超时。我会把它们放在downloadInfo
中。