0
在我開始使用條件變量之前,我試圖理解對象的等待原則。我編寫了一些代碼來了解更多內容,但不能按預期工作。java.lang.IllegalMonitorStateException雖然從同步塊調用等待
應該發生的事情是Waiter類在線程啓動時等待。 同時,通告程序類使用循環將一些元素添加到列表中。一旦通知已經這樣做了就會通知服務員應該簡單地打印,它已被通知,但我得到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)
這是代碼 正如你可以看到我m試圖在一個普通的鎖定對象上進行同步。
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();
}
}
任何指針,將不勝感激。在此先感謝
「最好使用notifyAll()而不是notify()。」這是一個非常全面的聲明,在答案中沒有任何理由...... –
乾杯@Stefan工作。我只使用通知,因爲我有一個線程正在等待。 –
@你是對的......如果你只有一個線程在等待通知,notify()也可以工作。如果您有多個Waiters,只有一個會收到通知。如果這是所需的行爲,那就沒問題。如果沒關係(因爲你知道,你只有一個Waiter線程),我仍然認爲使用notifyAll()是最好的做法,因爲Waiter對象不知道有多少對象正在等待鎖目的。通過使用notifyAll(),無論是否有其他人在等待鎖定,您都確定該通知是由服務員獲得的。 –