使用同步器同步线程写入文件
Synchronize threaded write into file using synchronizers
我正在通过多个线程写入一个文件,所以我使用了以下代码:
synchronized (this) {
BufferedWriter bw = new BufferedWriter(
new FileWriter(path, true));
bw.write(data);
}
出于教育目的,我想知道如何使用一些同步器(Semaphore、CountDownLatch、CyclicBarrier、Phaser 或 Exchanger)从本质上实现相同的目的:安全的多线程写入。
谢谢
老实说,从多个源写入同一个写入器的更好的近乎同义反复的方法是使用(阻塞)队列。这样,所有线程都可以将它们的消息放到队列中,写入线程可以从队列中挑选消息并将它们写入文件。它通常更容易实现,也更高效
-- 编辑--
示例:
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;
}
}
然后加入队列:
public class EnqueueMsgRunnable implements Runnable {
MyQueueableWriter q = ...;
q.put(myMessage);
q.put(myMessage2);
}
然后
for (int i =0; i < numSources; i++) {
EnqueueMsgRunnable r = new EnqueueMsgRunnable(...);
new Thread(r).start();
}
我正在通过多个线程写入一个文件,所以我使用了以下代码:
synchronized (this) {
BufferedWriter bw = new BufferedWriter(
new FileWriter(path, true));
bw.write(data);
}
出于教育目的,我想知道如何使用一些同步器(Semaphore、CountDownLatch、CyclicBarrier、Phaser 或 Exchanger)从本质上实现相同的目的:安全的多线程写入。
谢谢
老实说,从多个源写入同一个写入器的更好的近乎同义反复的方法是使用(阻塞)队列。这样,所有线程都可以将它们的消息放到队列中,写入线程可以从队列中挑选消息并将它们写入文件。它通常更容易实现,也更高效
-- 编辑--
示例:
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;
}
}
然后加入队列:
public class EnqueueMsgRunnable implements Runnable {
MyQueueableWriter q = ...;
q.put(myMessage);
q.put(myMessage2);
}
然后
for (int i =0; i < numSources; i++) {
EnqueueMsgRunnable r = new EnqueueMsgRunnable(...);
new Thread(r).start();
}