4

私はJavaRMIベースのプロジェクトに取り組んでいますClient-->Job Scheduler--> Server structure

以下に示すように、ジョブスケジューラクラスには2つのメソッドがあります。コメントは、コードの各行の目的を説明しています。

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()のメソッドの最初の呼び出しでIllegalMonitorStateExceptionが発生しacceptJob()ます。任意のアイデア、これを解決する方法。

ありがとう、Jiten

4

2 に答える 2

2

アプリケーションにとって論理的に正しいかどうかはわかりませんが、変更します

Thread.currentThread().wait();

lock.wait();

例外がスローされないようにする必要があります。フィードバックをお願いします。

編集:

両方の場所で、また変更します

Thread.currentThread().notifyAll();

編集^ 2:

説明については、こちらこちらをご覧ください

要するに:

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

行 1 のオブジェクトは、行 2 のオブジェクトと同じでなければなりません。同じでない場合、IllegalMonitorStateException がスローされるためです。

スレッドがオブジェクトのモニターで待機しようとしたことを示すか、指定されたモニターを所有せずにオブジェクトのモニターで待機している他のスレッドに通知するためにスローされます。

モニターを所有するということは、同期ブロック内にある必要があることを意味します (1、2 行目で示されているように)

于 2012-10-06T18:07:18.583 に答える
1
synchronized(lock) {
    Thread.currentThread().wait();
}

ロックしたオブジェクトのみを呼び出すことができるため、例外が発生waitしています..ここでは、オブジェクトをロックしています..ロック時にlock待機を呼び出す必要があります..

したがって、wait呼び出しを次のように変更する必要がありますlock.wait()

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

の場合も同じです。notify持っているオブジェクトで呼び出す必要がありますlocked

于 2012-10-06T18:22:26.637 に答える