Получение IllegalMonitorStateException при использовании wait() в планировщике заданий

Я работаю над проектом на основе 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();
        }
    }

Я получаю IllegalMonitorStateException при первом вызове wait() метод в acceptJob(), Есть идеи, как это решить.

Спасибо, Джитен

2 ответа

Я не знаю, логично ли это правильно для вашего приложения, но меняю

Thread.currentThread().wait();

в

lock.wait();

следует сделать исключение, чтобы не быть брошенным. Пожалуйста, оставьте отзыв.

РЕДАКТИРОВАТЬ:

в обоих местах, а также изменить

Thread.currentThread().notifyAll();

EDIT^2:

для объяснения смотрите здесь и здесь

короче:

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

объект из строки 1 должен быть тем же объектом, что и объект в строке 2, потому что если они не совпадают, генерируется исключение IllegalMonitorStateException

Брошенный, чтобы указать, что поток попытался ждать на мониторе объекта или уведомить другие потоки, ожидающие на мониторе объекта, не имея указанного монитора.

если владение монитором будет означать, что он должен находиться внутри синхронизированного блока (как показано в строках 1,2)

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

Вы получаете исключение, потому что вы можете только позвонить wait на объект, который вы заблокировали.. Здесь у вас есть замок на объекте lock.. так что ждать нужно вызвать на замок..

Итак, вы должны изменить свой wait позвонить lock.wait()

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

Тот же случай с notifyнужно вызвать его на объекте у вас есть locked..

Другие вопросы по тегам