2

我正在处理大型数据集,在构建模型后,我使用多线程(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();

当我收到每个可调用的结果时,将其输出到文件中。此输出是否与初始 Callables 列表的生成顺序完全相同?尽管有些人先于其他人完成?似乎应该但不确定。

此外,我预计总共有 620 万字节将写入输出文件。但我得到了额外的 2000 字节(是的,免费)。这弄乱了我的提交,我认为这是因为一些并发问题。我在小型数据集上对此进行了测试,它似乎在那里工作正常(预期和接收到 264 个字节)。

我在 Executor 框架或 Futures 上做错了什么?

4

2 回答 2

0

问:顺序是否与为任务指定的顺序相同?的。

从 API:

返回:代表任务的 Future 列表,其顺序与给定任务列表的迭代器生成的顺序相同。如果操作没有超时,则每个任务都已完成。如果确实超时,其中一些任务将无法完成。

至于“额外”字节:您是否尝试过按顺序执行所有这些(即,不使用执行程序)并检查是否获得不同的结果?似乎您的问题不在提供的代码范围内(并且可能不是由于并发性)。

于 2011-04-06T00:31:59.047 回答
0

可调用对象的执行顺序与您在此处的代码无关。您按照将期货存储在列表中的顺序编写结果。即使它们以相反的顺序执行,文件应该看起来与您的文件写入是单线程的相同。

我怀疑您的可调用对象正在相互交互,并且根据您使用的核心数量,您会得到不同的结果。例如,您可能正在使用 SimpleDateFormat。

我建议你在同一个程序中运行两次,数据集在短时间内完成。首先在线程池中仅使用一个线程运行它,第二次使用 24 个线程运行它 您应该能够比较两次运行的结果,Arrays.equals(byte[], byte[])并看到您得到完全相同的结果。

于 2011-04-06T07:13:51.337 回答