[英]Getting IllegalMonitorStateException while using wait() in Job scheduler
I'm working on a Java RMI based project which has Client-->Job Scheduler--> Server structure
. 我正在开发一个基于Java RMI的项目,它有
Client-->Job Scheduler--> Server structure
。
I have two methods in Job scheduler class as given below. 我在Job scheduler类中有两个方法,如下所示。 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's the turn of current thread's 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'm getting IllegalMonitorStateException at the first call to wait()
method in acceptJob()
. 我在
acceptJob()
第一次调用wait()
方法时acceptJob()
。 Any idea, how to resolve this. 任何想法,如何解决这个问题。
Thanks, Jiten 谢谢,Jiten
I don't know is it logically correct for your application, but changing 我不知道你的应用程序在逻辑上是否正确,但改变了
Thread.currentThread().wait();
to 至
lock.wait();
should make the exception not to be thrown. 应该做出不被抛出的例外。 Please, feedback.
请反馈。
EDIT: 编辑:
in both places, and also change 在这两个地方,也有变化
Thread.currentThread().notifyAll();
EDIT^2: 编辑^ 2:
for explanation look here and here 在这里和这里解释一下
in short: 简而言之:
synchronized(object) { //1
object.{wait(),notify(),notifyAll()}; //2
}
object from line 1 must be the same object as the one in line 2, because if they are not the same IllegalMonitorStateException is thrown 第1行的对象必须与第2行中的对象相同 , 因为如果它们不相同则抛出IllegalMonitorStateException
Thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.
抛出此异常表示线程已尝试在对象的监视器上等待,或者在没有指定监视器的情况下通知在对象监视器上等待的其他线程。
where owning the monitor would mean that it needs to be inside the synchronized block (as shown in lines 1,2) 拥有监视器意味着它需要位于synchronized块内(如第1,2行所示)
synchronized(lock) {
Thread.currentThread().wait();
}
You are getting exception because, you can only call wait
upon the object that you have locked.. Here you have lock on the object lock
.. So wait should be called on lock.. 你正在获得异常,因为你只能在你锁定的对象上调用
wait
..这里你锁定了对象lock
..所以等待应该在锁上调用..
so, you should change your wait
call to lock.wait()
所以,您应该将
wait
调用更改为lock.wait()
synchronized(lock) {
lock.wait();
}
Same case is with notify
, you need to call it on the object you have locked
.. 同样的情况是
notify
,你需要在你locked
的对象上调用它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.