java - 排序时非常奇怪的 NullPointerException

标签 java multithreading executorservice

我有一个空指针异常,因为列表 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;
   }

Stack trace## Heading ##

有时 adPics 列表有 null 值。这就是 NPE 的原因。但是怎么办?分析线程中执行的代码,不可能加null值。如果下载图像出现问题,则会抛出 IOException。 imageNewFileName 不能为 null

此代码是 Java 8,它使用 Apache Commons IO 库。

最佳答案

awaitTermination 方法不会停止正在运行的线程。它只会等待所有线程完成或达到 timeout。因此您的线程仍在将项目添加到您的列表中。

此外,您还应该考虑到即使达到超时,下载和复制到文件系统仍在运行。

一个简单但不完美的解决方案是在达到超时时设置一个标志,并在添加更多项目之前检查该标志。

更好的方法是在达到超时后中断线程。这还应该包括中断下载和文件复制。

关于java - 排序时非常奇怪的 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38903232/

相关文章:

java - 如何使 Splunk 查询区分大小写

c - 线程结束,结束整个程序?

java - 如何等待ExecutorService中所有提交的任务完成而不关闭?

java - JNI 线程导致 SIGSEGV Cypress fx2lp USB 芯片

JavaFX:stage.setOnCloseRequest() 不起作用

java - Guice 和属性文件

java - 从多个类访问未同步的 map

java - 为什么我的 JLabel 不能在循环中正确更新?

spring - 在同一上下文中支持多个线程池

java - ExecutorService 应该在 bean 的整个生命周期中都处于 Activity 状态,或者应该具有狭窄的(方法)范围