简体   繁体   English

从同步块中调用wait时发生java.lang.IllegalMonitorStateException

[英]java.lang.IllegalMonitorStateException whilst calling wait from synchronized block

Before I move onto using Condition variables I'm trying to understand object wait principles. 在继续使用Condition变量之前,我试图了解对象等待原理。 I wrote a little code to understand more but its not working as expected. 我写了一些代码以了解更多信息,但是它没有按预期工作。

What is supposed to happen is a Waiter class waits upon thread start. 应该发生的是Waiter类在线程启动时等待。 Meanwhile the Notifier class adds some elements to a list using a loop. 同时,Notifier类使用循环将一些元素添加到列表中。 Once the Notifier has done this it notifies the Waiter which should simply print that it has been notified but i get illegalmonitorstate exception 通知程序完成此操作后,它会通知服务员,该服务员应简单地打印已收到通知,但我收到了非法的monitorstate异常

This is my output 这是我的输出

Exception in thread "Waiter Thread" java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at tutorials.waitnotify.Waiter.run(Waiter.java:26)
at java.lang.Thread.run(Thread.java:745)
0 [Waiter Thread] DEBUG tutorials.waitnotify.Waiter  - Starting waiter....
2002 [Notifier Thread] DEBUG tutorials.waitnotify.Waiter  - Starting     
notifier...
3005 [Notifier Thread] DEBUG tutorials.waitnotify.Waiter  - Element added [1]
4007 [Notifier Thread] DEBUG tutorials.waitnotify.Waiter  - Element added [2]
5012 [Notifier Thread] DEBUG tutorials.waitnotify.Waiter  - Element added [3]
Exception in thread "Notifier Thread" java.lang.IllegalMonitorStateException
7022 [Notifier Thread] DEBUG tutorials.waitnotify.Waiter  - Object about to    
notify
at java.lang.Object.notify(Native Method)
at tutorials.waitnotify.Notifier.run(Notifier.java:42)
at java.lang.Thread.run(Thread.java:745)

This is the code As you can see I'm trying to synchronise on a common lock object. 这是代码如您所见,我正在尝试在通用锁定对象上进行同步。

public class Notifier implements Runnable {

private static final Logger LOGGER = LoggerFactory.getLogger(Waiter.class);
private List<Integer> list;
private Object commonLock;

public Notifier(Object lock) {
    this.list = new ArrayList<>();
    this.commonLock = lock;
}

public void run() {
    LOGGER.debug("Starting notifier....");
    synchronized (commonLock) {
        for (int i = 1; i <= 3; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ie) {
                LOGGER.debug("Interrupted");
            }
            list.add(i);
            LOGGER.debug("Element added [{}]", i);
        }
        LOGGER.debug("About to notify");
        notify();
    }
}
}

public class Waiter implements Runnable {

private static final Logger LOGGER = LoggerFactory.getLogger(Waiter.class);
private final Object commonLock;

public Waiter(Object lock) {
    this.commonLock = lock;
}

public void run() {
    LOGGER.debug("Starting waiter....");
    synchronized (commonLock) {
        try {
            wait(10000);
        } catch (InterruptedException ie) {
            LOGGER.debug("Interrupted");
        }
    }
    LOGGER.debug("Object been notified");
}
}

public class WaiterNotifierMain {

public static void main(String[] args) {
    BasicConfigurator.configure();

    Object lock = new Object();
    Waiter waiter = new Waiter(lock);
    Notifier notifier = new Notifier(lock);

    Thread waiterThread = new Thread(waiter);
    Thread notifierThread = new Thread(notifier);

    notifierThread.setName("Notifier Thread");
    waiterThread.setName("Waiter Thread");
    waiterThread.start();
    try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    notifierThread.start();
}
}

Any pointers would be appreciated. 任何指针将不胜感激。 Thanks in advance 提前致谢

You should do 你应该做

  • commonLock .wait(10000) commonLock .wait(10000)
  • commonLock .notify() commonLock .notify()

You get an exception because you're waiting and notifying on "this". 因为您正在等待并通知“此”,所以您会得到一个例外。 And you didn't synchronize on "this". 而且您没有在“ this”上同步。

You might consider using notifyAll() instead of notify(): 您可以考虑使用notifyAll()而不是notify():

If you plan to have multiple Waiter threads, keep in mind that notify() will only wake up one Waiter thread at a time. 如果您打算有多个Waiter线程,请记住,notify()一次只会唤醒一个Waiter线程。 If you want to wake up ALL Waiter threads at once, you should use the notifyAll() method instead. 如果要立即唤醒所有Waiter线程,则应改用notifyAll()方法。

Even if know that you will never have more than one Waiter thread, I consider it best practice to use notifyAll() instead of notify(), since the Notifier object doesn't know how many threads are listening on the object... 即使知道您永远不会有一个以上的Waiter线程,但我认为最好的方法是使用notifyAll()而不是notify(),因为Notifier对象不知道有多少线程正在该对象上侦听...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 当我以静态方式同步块调用wait()时,为什么Java会抛出java.lang.IllegalMonitorStateException? - Why Java throw java.lang.IllegalMonitorStateException when I invoke wait() in static way synchronized block? Android:java.lang.IllegalMonitorStateException:对象在wait()之前未被线程锁定 - Android: java.lang.IllegalMonitorStateException: object not locked by thread before wait() java.lang.IllegalMonitorStateException:对象在wait()之前未被线程锁定 - java.lang.IllegalMonitorStateException: object not locked by thread before wait() Android java.lang.IllegalMonitorStateException:对象在wait()之前未被线程锁定 - Android java.lang.IllegalMonitorStateException: object not locked by thread before wait() java.lang.IllegalMonitorStateException:在等待()之前对象没有被线程锁定? - java.lang.IllegalMonitorStateException: object not locked by thread before wait()? 超时时发生java.lang.IllegalMonitorStateException - java.lang.IllegalMonitorStateException on timeout 如何在不获取java.lang.IllegalMonitorStateException的情况下更改在同步块中获取的锁,对其进行更改以及notifyAll()? - how can I change the lock I have aquired in a synchronized block, change it, and notifyAll() without getting java.lang.IllegalMonitorStateException? 调用signal()时抛出java.lang.IllegalMonitorStateException - java.lang.IllegalMonitorStateException trhown when calling signal() java.lang.IllegalMonitorStateException 从线程中运行的方法抛出 - java.lang.IllegalMonitorStateException being thrown from methods running in threads java.lang.IllegalMonitorStateException (java selenium) - java.lang.IllegalMonitorStateException (java selenium)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM