Java 在作业计划程序中使用wait()时获取IllegalMonitorStateException
我正在从事一个基于Java RMI的项目,该项目具有Java 在作业计划程序中使用wait()时获取IllegalMonitorStateException,java,illegalmonitorstateexcep,Java,Illegalmonitorstateexcep,我正在从事一个基于Java RMI的项目,该项目具有客户端-->作业调度器-->服务器结构 我在作业调度程序类中有两个方法,如下所示。注释解释了每行代码的用途 private ConcurrentLinkedQueue<Job> jobQueue; private ConcurrentLinkedQueue<ComputeServerRef> serverQueue; private final Object lock = new Object(); /**
客户端-->作业调度器-->服务器结构
我在作业调度程序类中有两个方法,如下所示。注释解释了每行代码的用途
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();
}
}
私有ConcurrentLinkedQueue作业队列;
私有ConcurrentLinkedQueue服务器队列;
私有最终对象锁=新对象();
/**
*从客户端接受新生成的作业,并使用空闲计算对其进行调度
*服务器或将其排入JobQueue,具体取决于空闲的可用性
*服务器队列中的计算服务器。
*
*@param作业对象
*
*@exception-RemoteException
*如果发生任何远程错误,则引发。
*/
公共作业acceptJob(作业作业)引发RemoteException
{
//向所有记录器报告“已安排的作业”。
eventGenerator.reportEvent(新作业计划预览)
(“Job”+Job.getJobName()+“scheduled”);
已同步(锁定)
{
while(true)
{
如果(!serverQueue.isEmpty())
{
//如果serverQueue不为空,则从中获取一台服务器,
//将其从服务器队列中删除并为其分配新作业。
ComputeServerRef csr=serverQueue.poll();
尝试
{
作业=csr.performJob(作业);
更新服务器状态(csr);
打破
}
捕获(远程异常)
{
继续;
}
}
其他的
{
jobQueue.add(作业);
试一试{
Thread.currentThread().wait();
}捕捉(中断异常e){
e、 printStackTrace();
System.out.println(“线程中断”);
}
//检查是否轮到当前线程的作业。
//如果没有,则转到等待();
而(!jobQueue.peek().getJobName().equals(job.getJobName()))
{
试一试{
Thread.currentThread().wait();
}捕捉(中断异常e){
e、 printStackTrace();
System.out.println(“线程中断”);
}
}
job=jobQueue.poll();
}
}
}
返回工作;
}
/**
*将新启动的计算服务器添加到服务器队列
*
*远程对象ComputeServer的@param csr引用。
*
*@exception-RemoteException
*如果发生任何远程错误,则引发
*/
public void updateServerStatus(ComputeServerRef csr)引发RemoteException
{
已同步(锁定)
{
添加(csr);
Thread.currentThread().notifyAll();
}
}
在acceptJob()
中第一次调用wait()
方法时,我得到了非法的MonitorStateException。任何想法,如何解决这个问题
谢谢,
Jiten我不知道它在逻辑上是否适合您的应用程序,但正在更改
Thread.currentThread().wait();
到
应该使异常不被抛出。请提供反馈
编辑:
在这两个地方,情况也会发生变化
Thread.currentThread().notifyAll();
编辑^2:
如需解释,请查看
简言之:
synchronized(object) { //1
object.{wait(),notify(),notifyAll()}; //2
}
第1行中的对象必须与第2行中的对象相同,如果它们不是相同的ILLEGALMonitorState,则抛出异常
抛出以指示线程试图在对象的监视器上等待,或通知在不拥有指定监视器的情况下在对象监视器上等待的其他线程
其中,拥有监视器意味着它需要位于同步块内(如第1、2行所示)
您将获得异常,因为您只能对已锁定的对象调用wait
。。在这里,您锁定了对象lock
。。所以应该在lock上调用wait
因此,您应该将wait
调用更改为lock.wait()
与
notify
的情况相同,您需要在已锁定的对象上调用它。@JitenPatel。。有什么问题吗??如果您调用了wait on locked object,它应该可以工作。如果您按照描述执行并发布了所有相关代码,那么您不应该得到非法的MonitorStateException。你所说的“它不工作”到底是什么意思?是它没有给出expexted结果,还是它引发异常?如果是,请编码和堆栈跟踪
synchronized(object) { //1
object.{wait(),notify(),notifyAll()}; //2
}
synchronized(lock) {
Thread.currentThread().wait();
}
synchronized(lock) {
lock.wait();
}