【发布时间】:2016-08-11 18:02:50
【问题描述】:
我有一个空指针异常,因为adPics 列表中有一些空值。它很少发生。怎么可能?
(此代码并行下载图像并保存在本地。)
List<String> downloadAdImages(List<String> 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 列表具有null 值。这就是 NPE 的原因。但是怎么做?分析线程中执行的代码,无法添加null值。如果下载图像有问题,它会抛出一个 IOException。 imageNewFileName 不能是 null。
此代码是 Java 8,它使用 Apache Commons IO lib。
【问题讨论】:
-
(关于问题,而不是反对票)我想这是因为您要从多个线程添加到列表中,但列表未正确同步。当你这样做时,可能会发生有趣的事情。
-
您确定
awaitTermination调用没有超时,并且您开始对adPics进行排序,同时向其中添加元素吗?不知道为什么会抛出 NPE,但ArrayList不是线程安全的,所以我想任何事情都可能发生。 -
@LuísSoares 你不会的。只有当前线程被中断时,您才会看到该消息。见docs.oracle.com/javase/8/docs/api/java/util/concurrent/…你不检查
awaitTermination的返回值所以你不知道它是否超时。 -
在
== null上设置条件断点很容易找出答案,不是吗? -
不要发布文本图像,而是将实际文本复制并粘贴到您的问题中。图片不能参与搜索结果,它们对视力受损的用户毫无用处,而且它们的可读性远低于原生浏览器文本。
标签: java multithreading executorservice