我正在开发一个基于 Java RMI 的项目,该项目具有 Client-->Job Scheduler--> Server structure
。
我在作业调度程序类中有两种方法,如下所示。注释解释了每一行代码的用途。
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();
}
}
我在
wait()
中第一次调用 acceptJob()
方法时收到 IllegalMonitorStateException 。任何想法,如何解决这个问题。谢谢,
时天
最佳答案
我不知道您的应用程序在逻辑上是否正确,但正在更改
Thread.currentThread().wait();
至
lock.wait();
应该使异常不被抛出。请反馈。
编辑:
在这两个地方,也改变
Thread.currentThread().notifyAll();
编辑^2:
解释看 here 和 here
简而言之:
synchronized(object) { //1
object.{wait(),notify(),notifyAll()}; //2
}
第 1 行的对象必须是 与第 2 行中的对象相同的 对象,如果它们不相同,则抛出 because IllegalMonitorStateException
拥有监视器意味着它需要在同步块(synchronized block)内(如第 1,2 行所示)