Java线程类:Java.lang.IllegalMonitorStateException

Java线程类:Java.lang.IllegalMonitorStateException,java,multithreading,synchronization,wait,notify,Java,Multithreading,Synchronization,Wait,Notify,这是我的第一篇帖子,如果我做错了,我很抱歉。 我试图理解Java中线程是如何工作的,特别是同步,这就是为什么我创建了一段小代码,应该打印1,2,3,4,5,6(在一个线程中),然后再打印第二个线程,这是第一个线程,然后打印6,5,4,3,2,1但它只执行前6个步骤,并告诉我线程t2中的wait方法存在监视器问题,线程t1中的notify all存在问题。也许我对对象的同步一无所知。这是我的密码: public class anObject extends Thread { long value

这是我的第一篇帖子,如果我做错了,我很抱歉。 我试图理解Java中线程是如何工作的,特别是同步,这就是为什么我创建了一段小代码,应该打印1,2,3,4,5,6(在一个线程中),然后再打印第二个线程,这是第一个线程,然后打印6,5,4,3,2,1但它只执行前6个步骤,并告诉我线程t2中的wait方法存在监视器问题,线程t1中的notify all存在问题。也许我对对象的同步一无所知。这是我的密码:

public class anObject extends Thread {

long value;
String name;

public anObject(long value, String name) {
    this.value = value;
    this.name = name;
}

public synchronized void add() {
    this.value++;
}

public synchronized void sub() {
    this.value--;
}

public static void main(String[] args) {

    anObject il = new anObject(0, "Bob");

    synchronized (il) {

        Thread t1 = new Thread(il) {
            public void run() {
                while (il.value > 0) {
                    try {
                        this.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                for (int i = 0; i < 6; i++) {
                    il.add();
                    System.out.println(il.value);
                    try {
                        sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                il.notifyAll();
            }
        };

        Thread t2 = new Thread(il) {
            public void run() {
                while (il.value < 6) {
                    try {
                        this.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                for (int j = 0; j < 6; j++) {
                    il.sub();
                    System.out.println(il.value);
                    try {
                        sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                il.notifyAll();
            }
        };

        t1.start();
        t2.start();

    }
}
非常感谢你的帮助!
您好

您现在正在做什么

synchronized (il)
只是从主线程抓取对象的监视器。但是在内部,您正在初始化两个新线程,并尝试从这两个最近初始化然后启动的线程的上下文中调用
wait()
方法。IllegalMonitorStateException的主要思想是,您试图调用一个方法,该方法使用对象锁定的上下文,而无需事先获取该对象的锁定。你能做的就是迅速改变

while (il.value > 0) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }


并在第二个代码块中进行相同的更改。但要真正做到这一点,我建议您使用一些描述多线程概念的强源代码。我想Oracle的基本java教程就可以了。

等待是在对象中定义的,这就是为什么会出现这种异常

我更喜欢专用的,以避免不可预知的监视器异常:

private final Object lock = new Object();


private static final class Lock { }
private final Object lock = new Lock();
对于notify或notifyAll对象,需要使用synchronized语句持有锁。此外,还应该定义一个循环来检查唤醒条件

synchronized (lock) {
    while (!isWakeupNeeded()) {
        lock.wait();
    }
}
通知:

synchronized (lock) {
    makeWakeupNeeded();
    lock.notifyAll();
}

好的,谢谢!我会看一下教程。所以你建议我创建一个名为lock的对象实例,并在线程中同步它,而不是同步这个对象?
synchronized (lock) {
    while (!isWakeupNeeded()) {
        lock.wait();
    }
}
synchronized (lock) {
    makeWakeupNeeded();
    lock.notifyAll();
}