14

什么可能导致我在这段代码中得到 IllegalMonitorStateException

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

我有点困惑,因为据我所知,正在运行的线程必须对调用通知的对象进行监控。在我看来,我的代码不会错,但不知何故。

4

1 回答 1

23

类型Integer或类似的?用另一个--替换不可变对象。Integer因此,您调用notify的对象与synchronized.

您的代码相当于:

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

你不是一个人。甚至在 J2SE 5.0 之前,我已经在一本书中看到了示例代码,它在同步块中分配了一个引用。一般来说,标记锁定字段是个好主意final

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

于 2010-01-12T18:37:49.197 回答