Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/376.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 非法监视状态例外_Java_Multithreading_Thread Safety - Fatal编程技术网

Java 非法监视状态例外

Java 非法监视状态例外,java,multithreading,thread-safety,Java,Multithreading,Thread Safety,无论何时调用wait()和notify()或notifyAll(),我都会得到一个非法的MonitorStateException。javadoc说,如果我的线程“试图等待一个对象的监视器,或者通知其他线程在没有拥有指定监视器的情况下等待一个对象的监视器,那么我应该得到这个异常。” 然而,这里有一个代码示例,我在其中调用上述方法 //note that doSomething will be called by a thread from another class, not this one

无论何时调用wait()和notify()或notifyAll(),我都会得到一个非法的MonitorStateException。javadoc说,如果我的线程“试图等待一个对象的监视器,或者通知其他线程在没有拥有指定监视器的情况下等待一个对象的监视器,那么我应该得到这个异常。”

然而,这里有一个代码示例,我在其中调用上述方法

//note that doSomething will be called by a thread from another class, not this one
public void doSomething(){
    while(objectsCurrentlyDoingSomething() >= thisClass'sCapacity){
         synchronized(objectLock){ //objectLock is created at top of class like this:
             wait(2000);           //private static final Object objectLock = new Object();
         }
    }

    //rest of code
}
然后,稍后我会释放一个线程来保持该锁,并说如果对象完成,将减少当前使用的对象数并通知()


您需要调用wait,并在objectLock上通知

e、 g

objectLock.wait()


您只需调用
wait()
您在
上调用它,您需要调用wait,并在objectLock上通知

e、 g

objectLock.wait()


如果您只需调用
wait()
您正在调用
this

正如z5h所指出的,您对wait()和notify()的调用应该在objectLock对象上进行:

//note that doSomething will be called by a thread from another class, not this one
public void doSomething(){
    while(objectsCurrentlyDoingSomething() >= thisClass'sCapacity){
         synchronized(objectLock){ //objectLock is created at top of class like this:
             objectLock.wait(2000);           //private static final Object objectLock = new Object();
         }
    }

    //rest of code
}


正如z5h所指出的,对wait()和notify()的调用应该在objectLock对象上进行:

//note that doSomething will be called by a thread from another class, not this one
public void doSomething(){
    while(objectsCurrentlyDoingSomething() >= thisClass'sCapacity){
         synchronized(objectLock){ //objectLock is created at top of class like this:
             objectLock.wait(2000);           //private static final Object objectLock = new Object();
         }
    }

    //rest of code
}


这两个地方的objectLock是指同一个监视器吗?@Nambari我不完全理解监视器是什么,所以我用谷歌搜索了一下。Wikipedia说,“在并发编程中,监视器是一个对象或模块,可供多个线程安全使用。监视器的定义特征是其方法是互斥执行的。也就是说,在每个时间点,最多一个线程可以执行其任何方法。”objectLock是最终的静态对象(),不能更改,但是调用它的类可以有多个线程同时执行它的方法。这两个位置的objectLock是否都引用同一个监视器?@Nambari我不完全理解监视器是什么,所以我用谷歌搜索了它。Wikipedia说,“在并发编程中,监视器是一个对象或模块,可供多个线程安全使用。监视器的定义特征是其方法是互斥执行的。也就是说,在每个时间点,最多一个线程可以执行其任何方法。”objectLock是无法更改的最终静态对象(),但是调用它的类可以有多个线程同时执行它的方法。即使我希望当前线程等待1秒,释放它对锁的保留,从而允许其他线程调用此方法并等待()如果需要?这是示例代码。您仍然可以传递所需的参数以等待。重要的一点是在同步对象(在您的例子中是objectLock)上调用它。尽管我希望当前线程等待1秒,但释放它对锁的保持,从而允许其他线程调用此方法,如果需要还可以调用wait()?这是示例代码。您仍然可以传递所需的参数以等待。重要的一点是在同步对象(在您的例子中是objectLock)上调用它。
....object finished......
synchronized(objectLock){
    objectLock.notify();
}