有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

多线程处理一个“不可能”的null返回使用Java IO读取文件

我正在使用完成服务来告诉我何时成功加载了一组文件。 这是读取文件的方法:

public static LocalDateColumn readLocalDateColumn(String fileName, ColumnMetadata metadata) throws IOException {
    LocalDateColumn dates = new LocalDateColumn(metadata);
    assert(dates != null);
    try (FileInputStream fis = new FileInputStream(fileName);
         SnappyFramedInputStream sis = new SnappyFramedInputStream(fis, true);
         DataInputStream dis = new DataInputStream(sis)) {
      boolean EOF = false;
      while (!EOF) {
        try {
          int cell = dis.readInt();
          dates.add(cell);
        } catch (EOFException e) {
          EOF = true;
        }
      }
    }
    //System.out.println(dates);
    return dates;
  }

请注意,dates在第一条语句中分配了一个值,该值由断言检查。还要注意倒数第二行:注释掉的打印语句。如果此语句未被注释掉,则返回值从不为空。当它被注释掉时,它是空的,大约是在相同数据上运行的时间的1/2

非常感谢您的帮助

顺便说一句,使用EOF异常捕获来查找文件结尾看起来很难看,但Snappy需要它才能正确操作。我在其他代码中使用过它,而且一直都很好

FWIW,上面的代码是使用CompletionService调用的 看起来是这样的:

List<Column> columnList = new ArrayList<>();
try {
  for (ColumnMetadata column : columnMetadata) {
    readerCompletionService.submit(() -> {
      columnList.add(readColumn(path + File.separator + column.getId(), column));
      return null;
    });
  }
  for (int i = 0; i < columnMetadata.size(); i++) {
    Future future = readerCompletionService.take();
    future.get();
  }
  for (Column c : columnList) {
    columns.put(c.id(), c);
  }

在执行到达最后一行时。也就是说:

columns.put(c.id(), c);

c有时是空的


共 (1) 个答案

  1. # 1 楼答案

    可以同时使用ArrayList,但该集合不是线程安全的。您应该尝试使用线程安全的集合,例如CopyOnWriteArrayList