Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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_Notify_Illegalmonitorstateexcep - Fatal编程技术网

Java 非法监视器状态异常

Java 非法监视器状态异常,java,multithreading,notify,illegalmonitorstateexcep,Java,Multithreading,Notify,Illegalmonitorstateexcep,是什么原因导致我在这段代码中得到非法的MonitorStateException synchronized(syncCount){ syncCount--; syncCount.notify(); } 我有点困惑,因为据我所知,运行线程必须在调用通知的对象上有监视器。在我看来,我的代码不可能是错的,但不知何故它是。类型是整数还是类似的--将不可变的整数对象替换为另一个对象。因此,您正在调用notify,调用对象与synchronized不同 您的代码相当于: Integer s

是什么原因导致我在这段代码中得到非法的MonitorStateException

synchronized(syncCount){
    syncCount--;
    syncCount.notify();
}

我有点困惑,因为据我所知,运行线程必须在调用通知的对象上有监视器。在我看来,我的代码不可能是错的,但不知何故它是。

类型是
整数
还是类似的
--
将不可变的
整数
对象替换为另一个对象。因此,您正在调用
notify
,调用对象与
synchronized
不同

您的代码相当于:

Integer syncConunt = Integer.valueOf(5);
[...]
synchronized (syncCount) {
    syncCount = Integer.valueOf(syncCount.intValue() + 1);
    syncCount.notify();
}
你并不孤单。甚至在J2SE5.0之前,我就在一本书中看到过在同步块中指定引用的示例代码。一般来说,最好标记锁定字段
final


另一个重要的一点是,代码在它不“拥有”的对象上同步
Integer
对象是共享的(
Integer.valueOf(int)
如果使用-128到127之间的值调用,可能会返回完全相同的实例,甚至更远)。如果这是由两段不相关的代码完成的,那么就会有隐藏的交互。这适用于在不相关代码之间共享实例的任何类型。常见的例子有
Integer
String
Class
(由静态同步方法使用)和
Thread
(在Sun的实现中,
Thread
恰好被用作
join
的锁)。

非常感谢。这就解决了问题。它可能会解决抛出的异常,但您应该理解Tom关于声明字段final的说法。在自己的同步块中声明新对象是非常不安全的