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

jjv*_*nio 38 java synchronization illegalmonitorstateexcep notify

为什么这个测试程序导致了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");
    }
}
Run Code Online (Sandbox Code Playgroud)

结果:

Exception in thread "main" java.lang.IllegalMonitorStateException
        at java.lang.Object.notifyAll(Native Method)
        at test.main(test.java:6)
Run Code Online (Sandbox Code Playgroud)

eri*_*son 54

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

但是,在您的情况下,由于自动装箱,您同步的对象与您调用的对象notifyAll不同.实际上,新的递增foo实例仍然局限于堆栈,并且在wait调用时不可能阻止其他线程.

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

  • 这是Autoboxing/unboxing的众多问题之一. (2认同)
  • @dmitrii,确实如此,但在这里您明确修改了引用。这适用于任何对象引用,而不仅仅是枚举。 (2认同)