为什么 notifyAll() 在 Integer 上同步时会引发 IllegalMonitorStateException?

为什么此测试程序导致 ?java.lang.IllegalMonitorStateException

public class test {
    static Integer foo = new Integer(1);
    public static void main(String[] args) {
        synchronized(foo) {
            foo++;
            foo.notifyAll();
        }
        System.err.println("Success");
    }
}

结果:

Exception in thread "main" java.lang.IllegalMonitorStateException
        at java.lang.Object.notifyAll(Native Method)
        at test.main(test.java:6)

答案 1

您已正确注意到必须从同步块调用。notifyAll

但是,在您的情况下,由于自动装箱,您同步的对象与您调用的对象不是您调用的同一实例。实际上,新的增量实例仍局限于堆栈,并且在调用时不会阻塞其他线程。notifyAllfoowait

您可以实现自己的可变计数器,并在其上执行同步。根据您的应用程序,您可能还会发现 AtomicInteger 可以满足您的需求。


答案 2

您还应该谨慎锁定或通知可以由JVM转储的对象,例如字符串和整数(以防止创建大量表示整数1或字符串“”的对象)。


推荐