Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Write to text file from multiple threads? [duplicate]

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.

like image 398
Marco Micheli Avatar asked Apr 05 '12 10:04

Marco Micheli


People also ask

Can multiple threads write to the same file?

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.

Can multiple threads write to the same file Python?

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.


3 Answers

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!!");
like image 181
BWitched Avatar answered Nov 03 '22 21:11

BWitched


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);
  }
}
like image 33
OldCurmudgeon Avatar answered Nov 03 '22 23:11

OldCurmudgeon


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
}
like image 21
George Avatar answered Nov 03 '22 23:11

George