Reputation: 901
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;
}
}
}
Upvotes: 3
Views: 768
Reputation: 13066
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.
Upvotes: 2
Reputation: 4307
Because this
in gh
and gh2
are different, this
is an instance of Hoge.
So when use Hoge.class
, there is noly one synchronized lock, rather than using this
which will use two different lock.
Upvotes: 2