I am trying to write some content to a file, through multiple threads in Java. Each thread reads a different input file, does some computation and writes some (different) content to the common output file. The problem is that in the end, the output file only contains the content written by the last terminating thread and not the content from the other threads. Relevant code for the threads -
public void run()
{
try
{
File file = new File("/home/output.txt");
if (!file.exists())
{
file.createNewFile();
}
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
BufferedReader br = new BufferedReader(new FileReader(inputfile)); // each thread reads a different input file
String line="";
while((line=br.readLine())!=null)
{
String id = line.trim(); // fetch id
StringBuffer sb = processId(userId); // process id
synchronized(this){
bw.write(sb.toString() + "\n"); // write to file
}
}
bw.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
How do i make all threads write their content to the common file ?
For your use case you would use a synchronized queue and modify each of your worker threads to add their log data to the master queue that the log thread uses for logging. You should NOT have multiple threads trying to write directly to the same file.
You can have multiple threads write to the same file - but one at a time. All threads will need to enter a synchronized block before writing to the file. In the P2P example - one way to implement it is to find the size of the file and create a empty file of that size.
Multiple threads accessing shared data simultaneously may lead to a timing dependent error known as data race condition. Data races may be hidden in the code without interfering or harming the program execution until the moment when threads are scheduled in a scenario (the condition) that break the program execution.
Because all threads share the same heap, and the heap is where all instance variables are stored, multiple threads can attempt to use the same object's instance variables concurrently.
Use the constructor for FileWriter
that uses append mode
FileWriter fw = new FileWriter(file.getAbsoluteFile(), true);
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