Si obj es una variable local y ningún otro hilo está evaluando con el fin de obtener un bloqueo en él as shown here entonces no importa. Por lo demás este es ineficaz y se aplica lo siguiente:
(Publicación de esto porque las otras respuestas no son lo suficientemente enérgica-- "probablemente" no es suficiente aquí - y no tienen suficientes detalles.)
Cada vez que un hilo encuentra un bloque sincronizado, antes de que pueda adquirir el bloqueo, tiene que descubrir qué objeto necesita bloquear, mediante la evaluación de la expresión en parens que sigue a la palabra clave sincronizada.
Si la referencia se actualiza después de que el hilo evalúa esta expresión, el hilo no tiene forma de saberlo. Procederá a adquirir el bloqueo en el objeto antiguo que identificó como el bloqueo anterior. Finalmente ingresa al bloqueo sincronizado del objeto antiguo, mientras que otro hilo (que intenta ingresar al bloque después de que el bloqueo cambió) ahora evalúa el bloqueo como el nuevo objeto y entra al mismo bloque del mismo objeto que contiene el nuevo bloqueo. y no tiene exclusión mutua.
La sección correspondiente en el JLS es 14.19. El hilo de ejecutar la instrucción sincronizado:
1) evalúa la expresión, entonces
2) adquiere el bloqueo en el valor que la expresión se evalúa, a continuación,
3) ejecuta el bloque.
No vuelve a visitar el paso de evaluación en el momento en que adquiere con éxito el bloqueo.
Este código está roto. No hagas esto Asegúrate de cosas que no cambian.
Solo debe bloquear en los campos 'finales' para evitar que esto ocurra. Es una mala idea. –