Get IllegalMonitorState exception when using wait () in Task Scheduler

I am working on a Java RMI based project that has Client-->Job Scheduler--> Server structure .

I have two methods in the task scheduler class, as shown below. Commenting explains the purpose of each line of code.

 private ConcurrentLinkedQueue<Job> jobQueue; private ConcurrentLinkedQueue<ComputeServerRef> serverQueue; private final Object lock = new Object(); /** * Accepts newly generated job from client and schedule it with idle Compute * Server or queue it in JobQueue depending on the availability of idle * Compute Server in serverQueue. * * @param job Job object * * @exception RemoteException * Thrown if any remote remote error occurred. */ public Job acceptJob(Job job) throws RemoteException { // Report a "Job scheduled" to all Loggers. eventGenerator.reportEvent(new JobSchedulerEvent ("Job "+job.getJobName()+" scheduled")); synchronized(lock) { while(true) { if (!serverQueue.isEmpty()) { // If serverQueue is not empty then get one server from it, // remove it from the server queue and assign it a new job. ComputeServerRef csr = serverQueue.poll(); try { job = csr.performJob(job); updateServerStatus(csr); break; } catch(RemoteException re) { continue; } } else { jobQueue.add(job); try{ Thread.currentThread().wait(); }catch(InterruptedException e){ e.printStackTrace(); System.out.println("Thread Interrupted"); } // Check if it the turn of current thread job. // If not then goto wait(); while (!jobQueue.peek().getJobName().equals(job.getJobName())) { try{ Thread.currentThread().wait(); }catch(InterruptedException e){ e.printStackTrace(); System.out.println("Thread Interrupted"); } } job=jobQueue.poll(); } } } return job; } /** * Adds newly started compute server to serverQueue * * @param csr reference of the remote object ComputeServer. * * @exception RemoteException * Thrown if any remote remote error occurred */ public void updateServerStatus(ComputeServerRef csr)throws RemoteException { synchronized(lock) { serverQueue.add(csr); Thread.currentThread().notifyAll(); } } 

I get an IllegalMonitorStateException the first time the wait() method is called in acceptJob() . Any idea how to solve this problem.

Thanks Jiten

+4
source share
2 answers

I don’t know if this is logical for your application, but change

 Thread.currentThread().wait(); 

to

 lock.wait(); 

should make an exception that will not be thrown. Please feedback.

EDIT:

in both places and also change

 Thread.currentThread().notifyAll(); 

EDIT ^ 2:

For an explanation, look here and here.

:

 synchronized(object) { //1 object.{wait(),notify(),notifyAll()}; //2 } 

the object from line 1 must be the same object as line 2, because if they are not the same IllegalMonitorStateException exception

Thrown to indicate that the thread tried to wait on the object’s monitor or notify other threads that are waiting for the object to be monitored without owning the specified monitor.

where ownership of the monitor means that it must be inside the synchronized block (as shown in lines 1,2)

+2
source
 synchronized(lock) { Thread.currentThread().wait(); } 

You get an exception because you can only call wait on an object that you have blocked. Here you have locked the lock object. Therefore, the wait should be called when blocking.

so you have to change your wait call to lock.wait()

 synchronized(lock) { lock.wait(); } 

In the same case with notify , you need to call it on the object that you have locked ..

+1
source

Source: https://habr.com/ru/post/1438182/


All Articles