Java wait()和notify()方法,总是发生非法的MonitorStateException,并告诉我当前线程不是所有者为什么? package pkg_1; 公共类ExponWait方法扩展线程{ 静态双精度x=新双精度(20); 公共静态void main(字符串[]args){ ExpOnWaitMethod T1=新的ExpOnWaitMethod(); ExpOnWaitMethod T2=新的ExpOnWaitMethod(); T1.start(); T2.start(); } 公开募捐{ Mag Mag=新Mag(); 已同步(x){ 试一试{ 对于(int i=1;i

Java wait()和notify()方法,总是发生非法的MonitorStateException,并告诉我当前线程不是所有者为什么? package pkg_1; 公共类ExponWait方法扩展线程{ 静态双精度x=新双精度(20); 公共静态void main(字符串[]args){ ExpOnWaitMethod T1=新的ExpOnWaitMethod(); ExpOnWaitMethod T2=新的ExpOnWaitMethod(); T1.start(); T2.start(); } 公开募捐{ Mag Mag=新Mag(); 已同步(x){ 试一试{ 对于(int i=1;i,java,multithreading,concurrency,Java,Multithreading,Concurrency,您需要在要等待的对象上保持锁定(您只能在已同步的块中调用它) 另外,在线程上调用wait是非常不寻常的,可能不是您想要的 我不知道你想做什么,但是你会把等待和睡眠混淆吗 如果要等待另一个线程完成,则在对对象调用wait之前,必须获取该对象的锁: package pkg_1; public class ExpOnWaitMethod extends Thread { static Double x = new Double(20); public static void m

您需要在要等待的对象上保持锁定(您只能在
已同步的
块中调用它)

另外,在
线程上调用
wait
是非常不寻常的,可能不是您想要的

我不知道你想做什么,但是你会把
等待
睡眠
混淆吗


如果要等待另一个线程完成,则在对对象调用
wait
之前,必须获取该对象的锁:

package pkg_1;

public class ExpOnWaitMethod extends Thread {

    static Double x = new Double(20);


    public static void main(String[] args) {

        ExpOnWaitMethod T1 = new ExpOnWaitMethod();
        ExpOnWaitMethod T2 = new ExpOnWaitMethod();

        T1.start();

        T2.start();

    }

    public void run() {

        Mag mag = new Mag();

        synchronized (x) {

            try {
                for (int i = 1; i < 10; i++) {
                    mag.nop(Thread.currentThread());
                    x = i * 2.0;

                }

            } catch (InterruptedException e) {

                e.printStackTrace();
            }

        }
    }

}

class Mag {
    char ccc = 'A';

    public void nop(Thread thr) throws InterruptedException {

        System.out.print(ccc + " ");
        ccc++;

        if (thr.getState().toString().equalsIgnoreCase("runnable"))
            Thread.currentThread().wait();
        //thr.notify();
    }
}
您的代码正在
线程
对象上调用
等待
,而没有先获取锁


我假设这只是一个简单的测试用例来显示您的问题,但是请注意,您可能希望在一个可以从所有线程访问的对象上调用
wait
,而不是在
线程
对象本身上调用。

应该有人引用API契约,它直接解释了这一点。如果方法引发异常,请阅读文档


如有疑问,请阅读合同。(新闻广播上的Bill McNeal总是把他的名字放在夹克口袋里,这是JavaDoc API的一个很好的比喻。请参阅下面的“疯狂准备”,并思考无法估量的问题。)

我同意在线程监视器上调用wait和在java.util.concurrent.Condition监视器上调用wait一样奇怪:)我们一直在穿越路径。干杯!
syncrhonized(obj)
{
    obj.wait();
}