Reputation: 143
I have a JPanel class which starts another thread using "implements runnable". This other thread will then at various points call a method in the JPanel class which on doing so will then need to wait for the user input. I have attempted to implement it like this:
Method in JPanel class called by other thread that needs to wait:
public void methodToWait()
{
while(conditionIsMet)
{
try
{
wait();
}
catch
{
e.printStackTrace();
}
}
}
Method in JPanel class that notifies on wait on user input:
public void mouseClicked(MouseEvent event)
{
notifyAll();
}
However, upon running the application it throws a "java.lang.IllegalMonitorStateException" upon calling the wait, why is it doing this and how do I resolve the issue?
Upvotes: 4
Views: 5572
Reputation: 28269
See the doc of wait
, notify
and notifyAll
:
Thorws IllegalMonitorStateException - if the current thread is not the owner of the object's monitor.
That means you can not call them until you have aquired the monitor lock, in other words, until you have entered the synchronized block or synchronized method(check this for more).
Another important thing is, you should synchronize on the same object.
wait
and notify
on this object.this
, so you should call this.wait()
and this.notify()
(keyword this
is not mandory).In this case, you need create an Object
as monitor lock and share it between different classes.
Compliant example:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
synchronized (obj) {
... // Prepare the condition
obj.notifyAll();
}
Noncompliant example:
void waitMethod() {
wait(); // throws IllegalMonitorStateException
}
void notifyMethod() {
notify(); // throws IllegalMonitorStateException
}
Noncompliant example:
synchronized (obj1) {
while (<condition does not hold>)
obj1.wait();
... // Perform action appropriate to condition
}
synchronized (obj2) {
... // call notifyAll on obj2 will not stop the wait on obj1
obj2.notifyAll();
}
Noncompliant example:
in class1
synchronized void waitMethod() {
while(someCondition()) {
wait();
}
}
in class2
synchronized void notifyMethod() {
notify(); // call notifyAll on class2 will not stop the wait on class1
}
Upvotes: 8