Java 使用显式锁/条件引发IllegalMonitorStateException

Java 使用显式锁/条件引发IllegalMonitorStateException,java,concurrency,locking,Java,Concurrency,Locking,我想使用显式的锁/条件变量(这是一个课程项目,要求采用这种方式)来实现这种工作流程:a是主类,它要求B不时地做一些工作。B有一个工人阶级C,他不断地询问B要做的新工作,并做它。C完成后,它将调用A的回调函数来通知A作业已完成 但是,当我尝试运行该程序时,当callback()尝试通知doit()函数时,我会得到一个非法的MonitorStateException exception in thread "Thread-0" java.lang.IllegalMonitorStateExcepti

我想使用显式的锁/条件变量(这是一个课程项目,要求采用这种方式)来实现这种工作流程:a是主类,它要求B不时地做一些工作。B有一个工人阶级C,他不断地询问B要做的新工作,并做它。C完成后,它将调用A的回调函数来通知A作业已完成

但是,当我尝试运行该程序时,当callback()尝试通知doit()函数时,我会得到一个非法的MonitorStateException

exception in thread "Thread-0" java.lang.IllegalMonitorStateException
        at java.lang.Object.notifyAll(Native Method)
        at Test$A.callback(Test.java:49)
        at Test$C.run(Test.java:115)
我查看了javadoc和一些关于这个异常的问答,但仍然不知道为什么我会得到这个

import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Condition;

public class Test {
    public class A
    {
        private ReentrantLock lock;
        private Condition cond;
        private boolean bool;
        private B b;
        public A()
        {
            this.lock = new ReentrantLock();
            this.cond = lock.newCondition();
            b = new B(this);
            bool = false;
        }

        public void doit()
        {
            try {
                lock.lock();
                b.letgo();
                while (!bool) {
                    System.out.println("A::doit() Block.");
                    cond.awaitUninterruptibly();
                }
                System.out.println("A::doit() Done.");
            }
            finally {
                lock.unlock();
            }
        }

        public void callback() {
            try {
                lock.lock();
                bool = true;
                cond.notify();
                System.out.println("A::callback() done.");
            }
            finally {
                lock.unlock();
            }
        }
    }

    public class B
    {
        private C c;
        private ReentrantLock lock;
        private Condition cond;
        private boolean bool;
        public B(A a)
        {
            this.lock = new ReentrantLock();
            this.cond = lock.newCondition();
            bool = false;
            c = new C(a, this);
            c.start();
        }

        public void letgo()
        {
            try {
                lock.lock();
                bool = true;
            }
            finally {
                lock.unlock();
            }
        }

        public void get()
        {
            try {
                lock.lock();
                while (!bool) {
                    cond.awaitUninterruptibly();
                }
                bool = false;
                return;
            }
            finally {
                lock.unlock();
            }
        }
    }

    public class C extends Thread
    {
        private A a;
        private B b;

        public C(A a, B b)
        {
            this.a = a;
            this.b = b;
        }

        public void run()
        {
            while (true) {
                b.get();
                a.callback();
            }
        }
    }

    public static void main(String args[])
    {
        Test t = new Test();
        t.test1();
    }

    public void test1()
    {
        A a = new A();
        a.doit();
    }
}
使用
条件
上的方法代替
notify()

虽然您可以在
条件
实例上成功地
同步
,然后使用传统的
wait()
notify()
方法,但如果您不使用并发类的扩展功能,您也可以只使用
对象


条件
旨在与等效方法
await()
signal()
以及它们的增强变体一起使用。

哪一行是Test$A.callback(Test.java:49)