2

I have a thread issue in my code that should not be happening - but is. So I'm trying to make some work around. I will try to explain my problems with simple code as I can - because the code that I'm experiencing the issue is big and complicated so in short the code:

...................
..................
void createAndRunThreads(){
   List<Path> pathList = //read path from DB readPath();
   for(Path p : pathList){
      RunJob rj = new RunJob(p);
      Thred t = new Thread(rj);
      t.start();
   }
}

class RunJob implements Runnable {
   private Path path;
   private ExecuteJob execJob;

   public RunJob(Path path){
      this.path = path;
      this.execJob = new ExecuteJob();
   }

   public void run() {
      execJob.execute(path);
   }

}

class ExecuteJob {

   private static Job curentExecutingJob;

   public void execute(Path path){
      //here every thread should get different job list from others but this is not happening
      //so what happens eventually two threads are executing the same Job at once and it gets messy
      List<Job> jobList = getJobsFromPath(path);

      for(Job job : jobList) {
         curentExecutingJob=job;

         //work around that I'm trying to do. So if other thread tries to run the same job has to wait on lock(I dont know if this is posible do) 
         synchronized(curentExecutingJob){
            if(job.getStatus.equals("redy")){
               //do sum initialization 
               //and databese changes 
               job.run();
            }   
         }  
      }
   }

}

So my concern is if this going to work - I don know if the object in the lock is compared by memory(need to be the exact object) or by equals(to implement equal on it)

What happens when the static curentExecutingJob member has one value-object in first thread and creates lock on that(in synchronized block) and second thread changes that value and tries to enter synchronized block(My expectation that I'm hoping to be is that thread-2 will continue with executing and only time that it would be block is when he will get the same Job from DB that previously the first thread got it)

I don't know if this approach can be done and has sense

Two thread are running the following code that is inside method

1    Job j = getJobByIdFromDB(1111);
2    if(j.status.equals("redye")){
3        do staff
4        make database changes 
5        j.run();
6        j.state="running";
7    }

The ThreadA is stop from executing in line 3 from JVM and his state is changed from running to runnable and is set to wait in the poll.

The ThreadB is given chance by the JVM and ThreadB executes lines 1, 2, 3, 4, 5, 6 that I don't want to happen. I want the first thread that enters the code in lines 2,3 to finish before someone from the rest threads have chances to enter the same code

Problem accomplish this is that the two threads are executing the example method with different instance so synchronized the whole method wont work - also I have other code that is been executed in this method and I don't want that to be synchronizing to
So is there solution for my problem Also if I make synchronized(this.class){} it will lose the benefits and sense of multithreading

2
  • Well, first of all, your variable curentExecutingJob is declared as static and will be overwritten and accessed concurrently. This approach is not really good this way. What are you expecting to accomplish with this scheme? Commented Aug 6, 2013 at 12:44
  • Have you considered an ExecutorService. It is a thread pool with a queue and it ensure each tasks is only run by one thread. Commented Aug 6, 2013 at 12:48

3 Answers 3

1

The problem is that the 'currentExecutingJob' is defined as static, meaning that all instances of ExecuteJob share the same 'instance' of this variable. In addition, you are setting the value of this variable outside of a synchronization block, which means that each thread will set it in an uncontrolled way. Your following synchronization block should have no practical impact whatsoever.

Given the way your sample code is written, it appears to me that you don't need any static variables and you don't need any synchronization, as there are no resources shared across multiple threads.

However, Your comments in the code indicate that you want to prevent two threads from executing the same job at the same time. Your code does not achieve this, as there is no comparison of running jobs to see if the same job is running, and even if there was a comparison, your getJobsFromPath() would need to to construct a job list such that the same object instance would need to be reused when two threads/paths encounter the same 'job'.

I don't see any of this in your code.

Sign up to request clarification or add additional context in comments.

Comments

0

Can't comment so I'll put it as an answer. Sorry.

The block

synchronized(curentExecutingJob)

will synchronize on the object curentExecutingJob (in your terms, memory). If you synchronize on another object otherExecutingJob with currentExecutingJob.equals(otherExecutingJob) == true, both synchronize statements will not influence each other.

To your question/problem: It would be helpful if you describe what getJobsFromPath is doing or should do and what you actually want to do and what your problem actually is. It's not really clear to me.

1 Comment

i guess he want to sync the threads which actually change the same object and make some trouble there, he want to sync all threads when they try to edit the same object to make sync between them in some order...
0

i saw your code that it check's for the status of job, if it is ready or not, well as i think this is not a afeasible way

you can use the Callable Interface instead of Runnable

here is an example detailed which may help you.

Java Concurrency

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.