user13084438
user13084438

Reputation:

Synchronize threaded write into file using synchronizers

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

Answers (1)

ControlAltDel
ControlAltDel

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

Related Questions