If we call wait()
, notify()
or notifyAll()
on an object without a synchronized
block, we get an IllegalMonitorStateException
at runtime.
Why doesn't the compiler flag me if I try to call these methods without a synchronized block?
Calling those methods only requires that the current thread be the owner of the object`s monitor. However, that could mean calling a method without synchronized from within the context of another synchronized block.
For example:
public void doWait(Object o) {
o.wait(); // you would like the compiler to flag this
}
// but in this case it is valid
synchronized(this)
{
doWait(this);
}
In general, there is now way to know at compile time whether any piece of code will be executed when the current thread does not hold a particular monitor, which is likely why the compiler does not even try to flag this.
It's not possible to prove that a method further up the stack didn't already obtain the monitor.
For example:
class Foo
{
void foo()
{
synchronized (bar)
{
bar.bar();
}
}
}
class Bar
{
void bar()
{
this.wait();
}
}
Would be legal (assuming bar
is an instance of Bar
), but impossible to prove that there are is no code that calls bar
without first obtaining the monitor.
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