导致我在此代码中出现IllegalMonitorStateException的原因
synchronized(syncCount){
syncCount--;
syncCount.notify();
}
我有点困惑,因为据我所知,正在运行的线程必须有对被调用通知的对象进行监视。在我看来,我的代码不会错,但不知何故它是。
答案 0 :(得分: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
个对象(如果使用-128到127之间的值调用,则Integer.valueOf(int)
将返回完全相同的实例,并且可能更进一步)。如果这是由两段不相关的代码完成的,那么就会隐藏相互作用。这适用于在不相关代码之间共享实例的任何类型。常见示例包括Integer
,String
,Class
(由静态同步方法使用)和Thread
(在Sun的实现中,Thread
恰好用作锁join
)。