我正在尝试提高应用程序中 I/O 的速度,因此我决定使用多个线程来存储它。文件在层次结构 book/symbol/file 中结构化,多个线程可能同时将多个文件保存在同一目录中。当我按顺序保存所有文件时,没有问题。但是,当多线程启动时,有时文件格式错误并且加载它会引发“IOException:无效块”。任何想法为什么在这种情况下并发可能会搞砸?
下面的代码:
private void storeAppendingTimestamps(Series timeSeries) throws MetricPersistException {
Metric metric = timeSeries.getMetric();
Path outPutFile;
try {
outPutFile = generateOutputFilePath(metric);
if (!Files.exists(outPutFile)) {
createNewFile(outPutFile);
}
} catch (IOException e) {
throw new PersistException("Cannot create output file for metric " + metric);
}
try (PrintWriter writer = new PrintWriter(new GZIPOutputStream(new FileOutputStream(outPutFile.toFile(), true)), true)) {
for (SeriesDataPoint dataPoint : timeSeries.getTimeSeriesPoints()) {
writer.println(String.format("%d %s", dataPoint.getTimestamp().getMillis(), formatPlain(dataPoint.getValue())));
}
writer.close();
} catch (IOException e) {
throw new MetricPersistException(String.format("IO Exception has occured while persisting metric %s: %s", metric, e.getMessage()));
}
}
以及拆分工作的代码:
private void persistTimeSeries(Collection<Series> allSeries, CompletionService<Void> executorService) throws MetricPersistException {
final LoggingCounter counter = new LoggingCounter(logger, "metric series file", 10000);
for (final MetricTimeSeries series : allSeries) {
executorService.submit(new Callable<Void>() {
@Override
public Void call() throws Exception {
persister.persistTimeSeries(series);
counter.increment();
return null;
}
});
}
for (int i = 0; i < allSeries.size(); i++) {
Future<Void> future = executorService.take();
future.get();
}
counter.finish();
}