我有一个空指针异常,因为列表adPics上有一些空值.它很少发生.这怎么可能?
(此代码并行下载图像并在本地保存.)
List downloadAdImages(List imagesUrls, final String itemFolder) {
final List adPics = new ArrayList<>();
final ExecutorService executor = newFixedThreadPool(20);
imagesUrls.forEach(
picUrl -> executor.submit(() -> {
try {
String imageNewFileName = imagesUrls.indexOf(picUrl) + "." + getExtension(picUrl);
String bigPicUrl = picUrl.replace("b.jpg", "ab.jpg"); // big version
copyURLToFile(new URL(bigPicUrl), new File(itemFolder, imageNewFileName), 10, 10);
adPics.add(imageNewFileName);
} catch (IOException ex) {
log.log(Level.WARNING, "Could not download image {0} ({1})", new Object[]{picUrl, ex.getMessage()});
}
}));
executor.shutdown();
try {
executor.awaitTermination(15L, MILLISECONDS);
} catch (InterruptedException ex) {
log.log(Level.WARNING, "Could not wait for all images downloads");
}
Collections.sort(adPics); // null values at list lead to NPE here. How are there null values?
return adPics;
}
有时,adPics列表具有空值.这就是NPE的原因.但是怎么样?分析线程中执行的代码,无法添加空值.如果下载图像时出现问题,则会抛出IOException. imageNewFileName不能为null.
此代码是Java 8,它使用Apache Commons IO lib.
最佳答案 方法awaitTermination不会停止正在运行的线程.它只等待所有线程完成或达到超时.因此,您的线程仍在向列表中添加项目.
此外,您应该考虑即使达到超时,下载和复制到文件系统也在运行.
一个简单但不完美的解决方案是在达到超时时设置一个标志,并在添加更多项之前检查标志.
更好的方法是在达到超时后中断线程.这还应包括中断下载和文件复制.