Search code examples
javasynchronizedsynchronized-block

Object in Synchronized code returned from a method


I want to have a synchronized block where the Object to synchronize is returned from a method call:

...
synchronized( someGetMethod() ) {
// synchronized block
}
...

Is there an assumption that the "someGetMethod" is synchronized or only the "// synchronized block" section?

Thank you in advance

Edit: I have a collection (Map of objects to lock). The "someGetMethod" checks if an object is present on the Map, if not it will add it and return it in order to be locked. From the answers below, I understand that the "someGetMethod" can return a value that is already on the Map, but just before entering the synchronized block, switch to another thread, which may remove the above value. As a result another thread may do the same check via "someGetMethod" and now get a different result.. So it seems I should make the remove from within the synchronized block, is there a better option?

Edit2: Thank you all for your help. I have found a similar question - Java synchronized block using method call to get synch object


Solution

  • someGetMethod() is an expression that is evaluated before the monitor associated with the result of the expression is locked by a thread.

    14.19. The synchronized Statement

    A synchronized statement is executed by first evaluating the Expression. Then:

    • If evaluation of the Expression completes abruptly for some reason, then the synchronized statement completes abruptly for the same reason.

    • Otherwise, if the value of the Expression is null, a NullPointerException is thrown.

    • Otherwise, let the non-null value of the Expression be V. The executing thread locks the monitor associated with V. Then the Block is executed, and then there is a choice:

      • If execution of the Block completes normally, then the monitor is unlocked and the synchronized statement completes normally.

      • If execution of the Block completes abruptly for any reason, then the monitor is unlocked and the synchronized statement completes abruptly for the same reason.

    You can't enter a synchronized block, evaluate the expression, and then look the monitor associated with the result. How did you enter the block without evaluating its expression in the first place? What monitor did you use to synchronise someGetMethod() itself?