可靠地从多个线程写入一个PrintWriter

时间:2011-10-14 22:12:51

标签: java multithreading file-io io

我遇到了一个问题,我有多个线程写入同一个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

3 个答案:

答案 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

瓶颈很可能是您的磁盘访问,因此添加更多线程可能无济于事。