非法监控状态异常

什么可能导致我得到非法监控状态异常在这个代码

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

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


答案 1

类型或类似? 将不可变对象替换为另一个对象。因此,您正在调用与 的对象不同的对象。Integer--Integernotifysynchronized

您的代码等效于:

Integer syncConunt = Integer.valueOf(5);
[...]
synchronized (syncCount) {
    syncCount = Integer.valueOf(syncCount.intValue() + 1);
    syncCount.notify();
}

您并不孤单。甚至在 J2SE 5.0 之前,我就已经看到过在一本书中发布的示例代码,这些代码在同步块中分配了一个引用。通常,最好标记 锁定字段 。final

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


答案 2