Reputation:
I'm writing to a file via multiple threads so I am using the following code:
synchronized (this) {
BufferedWriter bw = new BufferedWriter(
new FileWriter(path, true));
bw.write(data);
}
and I'm wondering for educational purposes how I can use some synchronizer (Semaphore, CountDownLatch, CyclicBarrier, Phaser or Exchanger) to essentially achieve the same thing: safe multithreaded writing.
Thanks
Upvotes: 1
Views: 71
Reputation: 35011
Honestly, the much better nearly tautological way to write from multiple sources to the same writer is to use a (blocking) queue. This way, all threads can drop their messages on the queue, and the writer thread can pick the messages off the queue and write them to the file. It's generally easier to implement, as well as more efficient
-- edit --
Example:
public class MyQueueableWriter implements Runnable {
private BlockingQueue<Msg> q = new BlockingQueue();
private FileOutputStream fis = ...;
private volatile boolean running = true;
public MyQueueableWriter(FileOutputStream fis) {
this.fis = fis;
}
public void run() {
try {
while (running) {
Message m = q.take();
fis.write(...);
}
fis.close();
} catch (IOException iox) {
...
}
}
public void addMsg(Msg m) {
q.put(m);
}
public void stop() {
running = false;
}
}
Then adding to the queue:
public class EnqueueMsgRunnable implements Runnable {
MyQueueableWriter q = ...;
q.put(myMessage);
q.put(myMessage2);
}
Then just
for (int i =0; i < numSources; i++) {
EnqueueMsgRunnable r = new EnqueueMsgRunnable(...);
new Thread(r).start();
}
Upvotes: 1