Search code examples
javaconcurrencysynchronized

Java method vs member synchronization


I know that java's synchronization primitive, when applied to a method, is the semantic equivalent of taking a lock out on the object itself for the duration of the method's execution.

However, I'm unclear on this primitive's contract w.r.t. methods that access specific members of the object concurrently. Is the contract that this primitive only protects concurrent access across other members that also use it, or across any member that synchronizes on any underlying member of this object?

For instance, If foo() and bar() in the example below are invoked concurrently, can this lead to data races on innerThing?

class Thing {
   InnerThing innerThing;
   OtherInnerThing otherInnerThing;

   public synchronized void foo() {
      innerThing.mutate();
    }
  
  public void bar() {
      synchronized(innerThing) {
            innerThing.mutate();
      }
   }
}

Solution

  • Is the contract that this primitive only protects concurrent access across other members that also use it, or across any member that synchronizes on any underlying member of this object.

    The former. All threads must synchronize on the same object.

    If thread 1 is sync'd on the instance, and thread 2 attempts to sync on some member object of that instance, thread 2 will not be blocked.

    This is implicit in the Java Language Specification; the wording talks about 'the same monitor'.