【发布时间】:2016-06-19 18:07:24
【问题描述】:
我正在使用完成服务来告诉我一组文件何时已成功加载。 这是读取文件的方法:
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;
}
请注意,日期在第一个由断言检查的语句中分配了一个值。还要注意倒数第二行:注释掉的打印语句。当这条语句被not注释掉时,返回值永远不会为空。当它被注释掉时,它是空的,大约是在相同数据上运行时间的 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 有时为空。
【问题讨论】:
-
当 println(这是一种同步方法)更改您的并发程序时,可能的结论是存在竞争条件,该条件被额外的同步解决/隐藏。
-
您是否真的在启用断言的情况下运行您的 java 运行时(
-eajava 可执行文件的参数)? -
比如columnList是并发使用的,虽然ArrayList不是线程安全的……
-
@Andre Holzner。是的。 -ea 已启用。
-
@assylias 这很好。我将替换为线程安全的集合并重试。
标签: java multithreading io