Java 使用多线程生成文件数据时出现的额外字节
我正在处理大规模数据集,在构建模型后,我使用多线程(Java中的整个项目),如下所示:Java 使用多线程生成文件数据时出现的额外字节,java,multithreading,executorservice,callable,Java,Multithreading,Executorservice,Callable,我正在处理大规模数据集,在构建模型后,我使用多线程(Java中的整个项目),如下所示: OutputStream out = new BufferedOutputStream(new FileOutputStream(outFile)); int i=0; Collection<Track1Callable> callables = new ArrayList<Track1Callable>(); // For each entry in the test file,
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();
OutputStream out=new BufferedOutputStream(new FileOutputStream(outFile));
int i=0;
Collection callables=new ArrayList();
//对于测试文件中的每个条目,都需要执行do watever。
//Track1Callable实际上处理该条目并返回一个双精度值。
对于(成对测试:新DataFileIterable)(
kddcupdateamodel.getTestFile(dataFileDirectory))){
PreferenceArray userTest=tests.getFirst();
添加(新的Track1Callable(recommender,userTest));
i++;
}
ExecutorService executor=Executors.newFixedThreadPool(核心)//24芯
列表结果=executor.invokeAll(可调用项);
executor.shutdown();
用于(未来结果:结果){
for(字节估计:result.get()){
写出(估计);
}
}
out.flush();
out.close();
当我从每个可调用对象收到结果时,将其输出到一个文件中。此输出是否与初始可调用项列表的顺序完全一致?尽管有些人比其他人先完成?似乎应该,但不确定
此外,我预计总共有620万字节写入outfile。但我得到了额外的2000字节(是免费的)。这把我的提交搞砸了,我想这是因为一些并发性问题。我在一个小数据集上测试了它,它在那里似乎工作得很好(预期和接收264字节)
Executor framework或Futures有什么问题吗?Q:订单是否与为任务指定的订单相同是 从API: 收益:期货的列表 以相同的方式表示任务 由生产商生产的顺序 给定任务列表的迭代器。如果 每次操作都没有超时 任务将已完成。如果是的话 超时,其中一些任务将无法执行 已经完成
至于“额外”字节:您是否尝试过按顺序(即不使用执行器)执行所有这些操作,并检查是否获得了不同的结果?您的问题似乎不在提供的代码范围内(可能不是由于并发性造成的)。Q:顺序是否与为任务指定的顺序相同是 从API: 收益:期货的列表 以相同的方式表示任务 由生产商生产的顺序 给定任务列表的迭代器。如果 每次操作都没有超时 任务将已完成。如果是的话 超时,其中一些任务将无法执行 已经完成
至于“额外”字节:您是否尝试过按顺序(即不使用执行器)执行所有这些操作,并检查是否获得了不同的结果?您的问题似乎不在提供的代码范围内(可能不是由于并发性)。可调用函数的执行顺序与这里的代码无关。您按照在列表中存储未来的顺序写入结果。即使它们是以相反的顺序执行的,文件也应该与文件写入是单线程的一样 我怀疑您的可调用项正在相互交互,根据您使用的核心数量,您会得到不同的结果。e、 g.您可能正在使用SimpleDataFormat
我建议您在同一个程序中使用一个在短时间内完成的数据集运行两次。首先使用线程池中的一个线程运行,第二次使用24个线程运行。您应该能够将两次运行的结果与
数组进行比较。equals(byte[],byte[])
,并确保得到完全相同的结果。可调用的执行顺序与此处的代码无关。您按照在列表中存储未来的顺序写入结果。即使它们是以相反的顺序执行的,文件也应该与文件写入是单线程的一样
我怀疑您的可调用项正在相互交互,根据您使用的核心数量,您会得到不同的结果。e、 g.您可能正在使用SimpleDataFormat
我建议您在同一个程序中使用一个在短时间内完成的数据集运行两次。首先使用线程池中的一个线程运行它,第二次使用24个线程运行它。您应该能够将两次运行的结果与
数组进行比较。等于(byte[],byte[])
,并确保得到完全相同的结果。非常感谢。实际上,我已经尝试过顺序版本,效果非常好。除了运行大约需要5天之外,没有其他问题。这是我从那以后唯一的改变,真奇怪。您是否确定所有这些可调用项都不会干扰任何其他项(即,它们同意获取资源)?完全正确。他们没有。它们只在独立用户上工作,没有共享资源。Okie推荐者模型实际上是一个共享资源,但它只是用来获得对{user item}对的偏好。只读。更重要的是,它的文档是线程安全的。非常感谢。实际上,我已经尝试过顺序版本,效果非常好。除了运行大约需要5天之外,没有其他问题。这是我从那以后唯一的改变,真奇怪。您是否确定所有这些可调用项都不会干扰任何其他项(即,它们同意获取资源)?完全正确。他们没有。它们只在独立用户上工作,没有共享资源。Okie推荐者模型实际上是一个共享资源,但它只是用来获得对{user item}对的偏好。只读。更重要的是,它的文档是线程安全的。它不应该有任何区别,但是你可以编写一个字节[]
,而不必循环它的所有字节:out.write(result.get(),0,result.get().length)
。如果你知道每个结果的大小(例如,如果总是相同的话),你可以添加一个测试来检查它。只是为了确保没有我