开发者

Reliably write from multiple threads to one PrintWriter

开发者 https://www.devze.com 2023-04-13 08:05 出处:网络
I\'m running into an issue where I have multiple threads that write to the same PrintWriter and not all the data is getting written to the file. I know the multi-threaded part is working co开发者_如何

I'm running into an issue where I have multiple threads that write to the same PrintWriter and not all the data is getting written to the file. I know the multi-threaded part is working co开发者_如何学JAVArrectly since I can print everything to the console. Synchronizing the write statements does not seem to be working. What could be the problem?

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


For synchronization to work, you should use the same object for all threads, e.g.:

...
synchronized (resultFile) {
...


Do you close the PrintWriter after the pool stops?

pool.shutdown();
final boolean terminated = pool.awaitTermination(8, TimeUnit.SECONDS);
if (!terminated) {
    throw new IllegalStateException("pool shutdown timeout");
}

resultFile.close();


A simpler solution is to ensure there is only one thread in the pool. This way you don't need to synchonize writing as there is only one thread.

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

It is quite likely the bottle neck is you disk access so adding more threads may not help.

0

精彩评论

暂无评论...
验证码 换一张
取 消