i have 20 threads that write with the println() function on a file called results.txt. How can i synchronize them all?
I note every time my program run i have different number of lines of text in results.txt.
Thank you.
Multiple threads read the same file at the same time. In this case, there is no conflict. If multiple threads write the same file at the same time, write data will be lost.
Writing to the same file from multiple threads concurrently is not thread safe and may result in a race condition. Thread-safe means that writing or appending to the same file from more than one thread may result in a race condition.
Access the file through a class that contains a synchronized method to write to the file. Only one thread at a time will be able to execute the method.
I think that Singleton pattern would fit for your problem:
package com.test.singleton;
public class Singleton {
private static final Singleton inst= new Singleton();
private Singleton() {
super();
}
public synchronized void writeToFile(String str) {
// Do whatever
}
public static Singleton getInstance() {
return inst;
}
}
Every time you need to write to your file, you only would have to call:
Singleton.getInstance().writeToFile("Hello!!");
Duplicate question ... duplicate answer. As I said here:
If you can hold your file as a FileOutputStream
you can lock it like this:
FileOutputStream file = ...
....
// Thread safe version.
void write(byte[] bytes) {
try {
boolean written = false;
do {
try {
// Lock it!
FileLock lock = file.getChannel().lock();
try {
// Write the bytes.
file.write(bytes);
written = true;
} finally {
// Release the lock.
lock.release();
}
} catch ( OverlappingFileLockException ofle ) {
try {
// Wait a bit
Thread.sleep(0);
} catch (InterruptedException ex) {
throw new InterruptedIOException ("Interrupted waiting for a file lock.");
}
}
} while (!written);
} catch (IOException ex) {
log.warn("Failed to lock " + fileName, ex);
}
}
You are intend to write data into one file. So if you try to lock the whole file, it'd better to use a single thread to do this job. Although you spawn 20 threads, but there is only one of them is running every time you call the method, the others are just waiting for the lock.
I recommend you use RandomAccessFile
to write data to your file. Then each thread can write some unique data into to the file without locking the whole file.
Some demo code as following
try {
final RandomAccessFile file = new RandomAccessFile("/path/to/your/result.txt", "rw");
final int numberOfThread = 20;
final int bufferSize = 512;
ExecutorService pool = Executors.newFixedThreadPool(numberOfThread);
final AtomicInteger byteCounter = new AtomicInteger(0);
final byte[] yourText = "Your data".getBytes();
for (int i = 0; i < yourText.length; i++) {
pool.submit(new Runnable() {
@Override
public void run() {
int start = byteCounter.getAndAdd(bufferSize);
int chunkSize = bufferSize;
if (start + bufferSize > yourText.length) {
chunkSize = yourText.length - start;
}
byte[] chunkData = new byte[chunkSize];
System.arraycopy(yourText, start, chunkData, 0, chunkSize);
try {
file.write(chunkData);
} catch (IOException e) {
//exception handle
}
}
});
}
file.close();
} catch (Exception e) {
//clean up
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With