我遇到了一个问题,我有多个线程写入同一个PrintWriter而不是所有数据都写入文件。我知道多线程部分工作正常,因为我可以将所有内容打印到控制台。同步write语句似乎不起作用。可能是什么问题?
ExecutorService pool = Executors.newFixedThreadPool(poolSize);
for (Integer i : map.keySet()) {
final Collection<String[]> set = map.get(i);
pool.submit(new Runnable() {
public void run() {
StringBuffer sb = Matcher.performCollectionMatch(params);
synchronized (this) {
resultFile.print(sb); //this is a PrintWriter - it does NOT capture all sb
resultFile.flush();
System.out.print(sb); //this actually prints out ALL sb
}
}
});
} //FOR loop
答案 0 :(得分:4)
要使同步起作用,您应该为所有线程使用相同的对象,例如:
...
synchronized (resultFile) {
...
答案 1 :(得分:3)
游泳池停止后你关闭PrintWriter
吗?
pool.shutdown();
final boolean terminated = pool.awaitTermination(8, TimeUnit.SECONDS);
if (!terminated) {
throw new IllegalStateException("pool shutdown timeout");
}
resultFile.close();
答案 2 :(得分:1)
更简单的解决方案是确保池中只有一个线程。这样您就不需要同步写入,因为只有一个线程。
ExecutorService pool = Executors.newSingleThreadedPool();
for (Integer i : map.keySet()) {
final Collection<String[]> set = map.get(i);
pool.executor(new Runnable() {
public void run() {
StringBuilder sb = Matcher.performCollectionMatch(params);
resultFile.print(sb); //this is a PrintWriter - it does NOT capture all sb
System.out.print(sb); //this actually prints out ALL sb
}
});
} //FOR loop
瓶颈很可能是您的磁盘访问,因此添加更多线程可能无济于事。