Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

137
Views
Threads occasionally blocking while writing to the same file

I am trying to read from two text files (having the same number of lines, i.e. 10000) using two separate threads, one file containing Strings and the other containing Integers. Afterwards I want to write in another text file (String,Integer) values from corresponding positions in the result sets, each on a distinct line. For these purposes I'm using two classes implementing the Runnable interface.

The problem I'm facing is that every time I run the program, there is a chance that one of the threads is blocking execution, and I don't understand why considering that I'm using wait() and notify() in a synchronized block. More specifically, at times the program runs successfully finishing execution, while in most cases it stops at various stages (e.g. ~3000 out 10000 lines written, or even ~500).

citireInteger is a reference to the other thread which is reading the Integer file.

Here is relevant code from the classes dealing with reading from the String and Integer files, respectively:

@Override
public void run(){

    ........
    try {
        pw = new PrintWriter(new BufferedWriter(new FileWriter("rezultat.txt", true)));

        for(int i = 0; i < strings.size(); i++){

            synchronized(this){
                pw.write(strings.get(i));
            }

            synchronized(citireInteger){
                citireInteger.notifyAll();
            }

            try{
                synchronized(this){
                    wait();
                }
            } catch(InterruptedException e){
                e.printStackTrace();
            }
        }
    } catch(FileNotFoundException e){
        e.printStackTrace();
    } catch(IOException e){
        e.printStackTrace();
    } finally{
        pw.close();
    }

    synchronized(citireInteger){
        citireInteger.notify();
    }
}

The thread reading the Integer file:

    public void run(){

    ...........

    try{
        pw = new PrintWriter(new BufferedWriter(new FileWriter("rezultat.txt", true)));

        for(int i = 0; i < ints.size(); i++){

            synchronized(this){
                pw.write(ints.get(i) + '\n');
                System.out.println(ints.get(i));
            }
            synchronized(citireString){
                citireString.notifyAll();
            }

            try{
                synchronized(this){
                    wait();
                }
            } catch(InterruptedException e){
                e.printStackTrace();
            }
        }
    } catch(FileNotFoundException e){
        e.printStackTrace();
    } catch(IOException e){
        e.printStackTrace();
    } finally{
        pw.close();
    }

    synchronized(citireString){
        citireString.notify();
    }
}
over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

What's happening is that one thread is calling notifyAll on the other thread, then getting switched out before synchronizing on its own writer to call wait. The other thread does its write, synchronizes on its writer, and calls wait. Then the first thread gets switched in again, synchronizes on its writer, and calls wait. There's your deadlock.

Better would be to have both threads synchronize on the same object to write. Best would be to store the data in memory in a thread safe way and write from a single thread once reading from both threads was complete.

over 4 years ago · Santiago Trujillo Report

0

When you notify the other thread, the other thread will only see that when the other threads is waiting for it. I the other thread is outside that synchronized block, and enters that synchronized block after it is notified, it will then wait for a notify that won't happen, or rather, than happened before it started to wait for it. It's hard to really determine what the objective of this exercise is, but I'm guessing it is about two threads taking turns doing a write. Ok, so, how about making the synchronized(citireInt/String) block encompass its entire code! This way, the other thread trying to obtain a lock will ONLY get that lock WHEN the other thread is waiting. That I think would guarantee no blocking and the result would be both threads taking turns, one by one.

Edit: not entirely exactly as I described, but the key points is where to synchronize...

   public void run()
   {
       ...........

       try
       {
           pw = new PrintWriter(new BufferedWriter(new FileWriter("rezultat.txt", true)));

           synchronized(this)
           {
               for(int i = 0; i < ints.size(); i++)
               {
                   pw.write(ints.get(i) + '\n');
                   System.out.println(ints.get(i));

                   synchronized (citireString)
                   {
                       citireString.notifyAll();
                   }

                   try
                   {
                       wait();
                   }
                   catch (InterruptedException e)
                   {
                       e.printStackTrace();
                   }
               }
           }
       }
       catch (Throwable e)
       {
           e.printStackTrace();
       }
       finally
       {
           pw.close();
       }
    }
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!