我正在开发一个大型数据集,在构建模型之后,我使用多线程(Java中的整个项目),如下所示:
OutputStream out = new BufferedOutputStream(new FileOutputStream(outFile));
int i=0;
Collection<Track1Callable> callables = new ArrayList<Track1Callable>();
// For each entry in the test file, do watever needs to be done.
// Track1Callable actually processes that entry and returns a double value.
for (Pair<PreferenceArray, long[]> tests : new DataFileIterable(
KDDCupDataModel.getTestFile(dataFileDirectory))) {
PreferenceArray userTest = tests.getFirst();
callables.add(new Track1Callable(recommender, userTest));
i++;
}
ExecutorService executor = Executors.newFixedThreadPool(cores); //24 cores
List<Future<byte[]>> results = executor.invokeAll(callables);
executor.shutdown();
for (Future<byte[]> result : results) {
for (byte estimate : result.get()) {
out.write(estimate);
}
}
out.flush();
out.close();
当我从每个callable收到结果时,将其输出到一个文件。这是否按照初始Callables列表的确切顺序输出?尽管有些人在其他人之前完成了吗?似乎应该但不确定。
另外,我希望将总共620万个字节写入outfile。但我得到额外的2000字节(是的免费)。这搞砸了我的提交,我认为这是因为一些并发问题。我在小数据集上测试了它,它似乎在那里工作正常(预期和接收264字节)。
任何错误我正在使用Executor框架或Futures?
答案 0 :(得分:0)
问:订单是否与为任务指定的顺序相同? 是即可。
来自API:
退货:期货清单 代表任务,在同一个 由...产生的顺序 给定任务列表的迭代器。如果 每个操作都没有超时 任务将完成。如果确实如此 超时,其中一些任务不会 已经完成了。
至于“额外”字节:您是否尝试按顺序执行所有这些操作(即,不使用执行程序)并检查是否获得了不同的结果?似乎您的问题超出了提供的代码(可能不是由于并发)。
答案 1 :(得分:0)
执行可调用程序的顺序与您在此处的代码无关。您按照将期货存储在列表中的顺序编写结果。即使它们以相反的顺序执行,文件应该与文件写入单线程相同。
我怀疑你的callables正在互相交互,你会得到不同的结果,具体取决于你使用的核心数量。例如您可能正在使用SimpleDateFormat。
我建议你在同一个程序中使用一个在短时间内完成的数据集运行两次。首先运行它,在线程池中只有一个线程,第二次运行24个线程你应该能够将两次运行的结果与Arrays.equals(byte[], byte[])
进行比较,看看你得到完全相同的结果。