java.lang.IllegalMonitorStateException 同时从同步块调用等待
java.lang.IllegalMonitorStateException whilst calling wait from synchronized block
在开始使用条件变量之前,我试图了解对象等待原则。我写了一些代码来了解更多,但它没有按预期工作。
应该发生的是 Waiter class 在线程启动时等待。
同时,通知程序 class 使用循环将一些元素添加到列表中。一旦通知程序完成此操作,它就会通知服务员,服务员应该简单地打印它已收到通知,但我得到 illegalmonitorstate 异常
这是我的输出
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)
这是代码
如您所见,我正在尝试在一个公共锁对象上进行同步。
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();
}
}
如有指点,我们将不胜感激。提前致谢
你应该做
- commonLock.wait(10000)
- commonLock.notify()
您在 "this" 上等待和通知,因此出现异常。而且您没有在 "this".
上同步
您可以考虑使用 notifyAll() 而不是 notify():
如果您计划拥有多个 Waiter 线程,请记住 notify() 一次只会唤醒一个 Waiter 线程。如果你想一次唤醒所有的 Waiter 线程,你应该使用 notifyAll() 方法。
即使知道你永远不会有一个以上的 Waiter 线程,我认为最好的做法是使用 notifyAll() 而不是 notify(),因为 Notifier 对象不知道有多少线程在监听对象...
在开始使用条件变量之前,我试图了解对象等待原则。我写了一些代码来了解更多,但它没有按预期工作。
应该发生的是 Waiter class 在线程启动时等待。 同时,通知程序 class 使用循环将一些元素添加到列表中。一旦通知程序完成此操作,它就会通知服务员,服务员应该简单地打印它已收到通知,但我得到 illegalmonitorstate 异常
这是我的输出
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)
这是代码 如您所见,我正在尝试在一个公共锁对象上进行同步。
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();
}
}
如有指点,我们将不胜感激。提前致谢
你应该做
- commonLock.wait(10000)
- commonLock.notify()
您在 "this" 上等待和通知,因此出现异常。而且您没有在 "this".
上同步您可以考虑使用 notifyAll() 而不是 notify():
如果您计划拥有多个 Waiter 线程,请记住 notify() 一次只会唤醒一个 Waiter 线程。如果你想一次唤醒所有的 Waiter 线程,你应该使用 notifyAll() 方法。
即使知道你永远不会有一个以上的 Waiter 线程,我认为最好的做法是使用 notifyAll() 而不是 notify(),因为 Notifier 对象不知道有多少线程在监听对象...