Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why isn't calling wait(), notify() or notifyAll() without a synchronized block not a compiler error?

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?

like image 264
c_maker Avatar asked Feb 13 '23 19:02

c_maker


2 Answers

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.

like image 124
ChaseMedallion Avatar answered Feb 16 '23 08:02

ChaseMedallion


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.

like image 39
SimonC Avatar answered Feb 16 '23 07:02

SimonC