我制作了一个程序,它使用单个线程将文件中的数据读入链表,然后将其称为LL1。从这里我创建了一个线程池,它为每个线程分配一个处理任务,该任务从LL1读取数据并将其计算输出到新的链表。 从这里我需要将每个线程新的链表输出到一个SINGLE文件中。我试图在顺序块中输出每个链表,以便线程不混合数据,所以我使用了一个同步点,如下所示:
public synchronized void appendContents(List<Vector2> output1) {
try {
sFileName = outFilePath + "\\file" +fileCount+ ".cntr";
File oFile = new File(sFileName);
if (!oFile.exists()) {
oFile.createNewFile();
}
if (oFile.canWrite()) {
//BufferedWriter oWriter = new BufferedWriter(new FileWriter(sFileName, true));
FileWriter wstream = new FileWriter(oFile, true);
BufferedWriter outWriter = new BufferedWriter(wstream);
for(int i = 0; i < output1.size(); i++)
{
//replace the space marker values with a newline
if(output1.get(i).y == -200.0){
outWriter.newLine();
}else{
outWriter.write(String.valueOf(output1.get(i).x) + " " + String.valueOf(output1.get(i).y) + " " + String.valueOf(interval));
outWriter.newLine();
}
}
outWriter.close();
}
}
catch (IOException oException) {
throw new IllegalArgumentException("Error appending/File cannot be written: \n" + sFileName);
}
我面临的问题是数据不按我需要的顺序出现,即
list1 value list1 value
list1 value _______________\ list2 value
list1 value ________________\ list1 value
list2 value RATHER THAN ____/ list3 value
list2 value ---------------/ list2 value
list2 value list1 value
list3 value list2 value
list3 value list1 value
list3 value list3 value
list3 value list3 value
如果有人能够朝着正确的方向迈出一步,我们将不胜感激。 谢谢,
杰克
答案 0 :(得分:2)
synchronized
的目的是在共享资源上进行同步,以便一次只有一个Thread
可以访问关键部分。我将假设您正在生成三个Thread
个实例,每个实例都在自己的对象上调用appendContents
。
synchronized
方法隐式地在this
上同步,但由于所有三个Thread
都在不同的对象上同步,即。一个不同的this
,没有任何一个阻止它们。
答案 1 :(得分:1)
据我了解,每次为每个列表元素执行新任务时都会运行?
然后你就可以编写Callable任务 - &gt;将结果保存在List vs result(resultFeatureFromList)中的Feature.Put Feature中。最后做一些像这样的事情: 我使用来自Guava Lib的函数;
Iterables.transform(resultList<Feature>,new Function(){
public resultComputition apply(Feature resultFeatureFromList){
return resultFeatureFromList.get();
}
});
总而言之,您将以正确的顺序运行所有任务。拉完后只需等待结果。
答案 2 :(得分:1)
从user2870704's answer开始,您可以按如下方式构建您的应用程序:
Callable
任务; Future
存储在列表或列表列表中 - 您可以定义所需的粒度; 举个例子:
void readAndOutput(String inputFilePath, String outputFilePath) {
List<List<Future<Result>>> results = readAndSpawnTask(inputFilePath);
PrintWriter out = new PrintWriter(new File(outputFilePath));
for (List<Future<Result>> block : results) {
for (Future<Result> r : block) {
out.println(r.get().toString());
}
}
out.flush();
out.close();
}
List<List<Future<Result>>> readAndSpawnTask(String path) {
List<List<Future<Result>>> results = new ArrayList<>(numOfBlocks);
BufferedReader in = new BufferedReader(new FileReader(new File(path)));
for (int i = 0; i < numOfBlocks; ++i) {
results.add(new LinkedList<Future<Result>>());
}
for (String line = in.readLine(); line != null; line = in.readLine()) {
int respectiveBlock;
Callable<Result> task;
// Process line and convert it into a task of your own.
// Determine in which block the result goes into.
Future<Result> r = threadPool.submit(task);
results.get(respectiveBlock).add(r);
}
in.close();
return results;
}
如果您想要和/或需要并发,我们的想法是在单个线程中访问文件。使用Future
列表,您可以保证以正确的顺序编写结果,并且主线程将阻塞,直到所需的结果准备就绪。
当然,您仍然需要考虑上述代码中引发的可能异常。