My code gives me a problem.
My code throws IllegalMonitorStateException in setStr which is in Hoge class.
I change Hoge.class into this in setStr. My code correctly finished!
But why did it finish normally?
public class Sample {
static Hoge gh = new Hoge();
static Hoge gh2 = new Hoge();
public static void main(String[] args) {
new Thread() {
private Hoge h2 = gh;
public void run() {
System.out.println("start initialize");
h2.setStr("BazzBazz");
System.out.println("end initialize");
System.out.println("start thread 1");
System.out.println(h2.getStr("thread-1"));
System.out.println("end thread 1");
}
}.start();
new Thread() {
private Hoge h2 = gh2;
public void run() {
System.out.println("start thread 2");
System.out.println(h2.getStr("thread-2"));
System.out.println("end thread 2");
}
}.start();
}
}
class Hoge {
private String fuga = "fugafuga";
public void setStr(String str) {
synchronized(Hoge.class) { //<-HERE ! change "Hoge.class" into "this".
fuga = str;
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
String getStr(String suffix) {
synchronized(Hoge.class) {
return suffix+ fuga;
}
}
}
YoursetStr method should be like this:
public void setStr(String str) {
synchronized(Hoge.class) { //<-HERE ! change "Hoge.class" into "this".
fuga = str;
try {
Hoge.class.wait();//call wait on Hoge.class
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
You should use Hoge.clas.wait() instead of wait(). Why?
Because , as specified in oracle documentation about wait() :
This method should only be called by a thread that is the owner of this object's monitor.
i.e a thread can't invoke a wait on an object until it owns that object's lock. Otherwise it will throw IllegalMonitorStateException . Here , you are acquiring lock on object of Class of Hoge(i.e Hoge.class) called as class level lock , but was calling wait on the current object of Hoge(this). So it was leading to IllegalMonitorStateException. That's why your code was working fine when you acquiring lock on the current object (this) because wait() in that case was called on the current object (this) itself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With