Multithreading Problem

I multithread a process for each record returned from the query.
The problem is that I call addToFinalLetter() as each job completes.
I actually need to make sure that addToFinalLetter() in the order the query returns the records so that they are in the correct order.
I'm having a hard time explaining what I mean, so if anybody has any idea what I'm talking about or questions.. I would appreciate any help.

Thanks!

Tom

public void run()
  {
    try
    {
        workers = new ArrayList();

        for ( int i = 0; i < simulWorkers; i++ )
        {
          workers.add( i, new Worker( getNextLogSeqno(), printSeqno, dbName, imageDbName, userId ) );
          ((Worker) workers.get( i ) ).start();
        }

        while ( completed < letterCount )
        {
          for ( int i = 0; i < simulWorkers; i++ )
          {
            worker = ((Worker) workers.get( i ) );

            if ( worker.isDone() )
            {
              worker.done = false;
             
              addToFinalLetter( worker.getLetter() );
             
              completed++;
             
              logSeqno = getNextLogSeqno();

              if ( logSeqno != 0 )
              {
                workers.set( i, new Worker( logSeqno, printSeqno, dbName, imageDbName, userId ) );  
               
                ((Worker) workers.get( i ) ).start();
              }
            }
          }
        }
     
      workers = null;
     
      done = true;
    }
    catch ( Exception ignore ) {}
  }

NorCal19Asked:
Who is Participating?
 
JugglerWConnect With a Mentor Commented:
Mixture of Java and Pseudocode, but should give you an idea:

Integer seqNumber = new Integer(0);

while ( !worker.isDone() )
{
    if ( worker.getSeqNumber().equals( seqNumber ) )
    {
        addToFinalLetter( worker.getLetter() );
        increment seqNumber;
        seqNumber.notifiyAll(); // let other workers try to finish
    }
    else
            seqNumber.wait(); // wait till my number will come
}

0
 
CEHJConnect With a Mentor Commented:
You should probably use wait/notify to synchronize on the sequence number. Make the thread wait if it's not got the right sequence number. If a thread is allowed access, it should call notify after writing
0
 
NorCal19Author Commented:
Can you please show me an example of how this would work?

I tried briefly to use the wait and notify but I kept getting some ObjectMonitorException....

Thanks,

Tom
0
 
NorCal19Author Commented:
I actually ended up doing it in a really ghetto way:

I first loop through the query and load the logSeqnos into an ArrayList I call sequence. This will be the order I must append them later.

Then, I also have a HashMap called dataPairs that is populated as each worker completes. The key for the HashMap is the log seqno and the value is the object that I pass to the append method.

So once all workers have completed I can run the following:

private void createDocument()
  {
    try
    {
      for ( int i = 0; i <= sequence.size(); i++ )
      {
        finalLetter.appendDocument((Letter) dataPairs.get( sequence.get( i ) ) );
      }
    }
    catch ( Exception ignore ) {}
  }

Thank you both for your help.

I will split the points evenly
0
 
CEHJCommented:
:-)
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.