me encontré con algunos (producción!) De código que se ve como el siguiente fragmento:Asignación de un objeto dentro de un bloque sincronizado sobre la base de ese objeto (Java)
synchronized(some_object) {
some_object = new some_object()
}
Yo esperaría que esto sea objeto de todo tipo de condiciones de carrera horribles, y que un segundo subproceso podría entrar en este bloque cuando se crea el nuevo objeto. Mis chuletas de Java no son lo suficientemente buenas como para indicar definitivamente el comportamiento esperado de arriba, por lo que es curioso lo que ustedes tienen que decir antes de refactorizar esto.
No está escrito así. En mi caso, la clase tiene la variable some_object que se usa para el bloque de sincronización, y esta variable se reasigna dentro de ese mismo bloque. –
+1 la clave aquí es que la sincronización se refiere al objeto, no a la referencia. Después de que se ejecuta y asigna el 'nuevo', todavía está bloqueado en el objeto viejo. El nuevo objeto no está bloqueado en este punto. Cuando se sale del bloque sincronizado, se libera el bloqueo del antiguo objeto, y si no existen otras referencias a él, es elegible para gc. Si hay más código en el bloque sychronized real y depende de que el bloqueo se transfiera de alguna manera al nuevo objeto, entonces es posible que tenga un problema. –
Gracias Jim. El hecho de que el bloqueo esté en el objeto y no en la referencia tiene sentido para mí. Lo que me confundió fue cuando el objeto referenciado por esa variable cambió, ¿otro hilo vería un objeto desbloqueado diferente y entraría en el bloque nuevamente, o los mecanismos de un bloqueo sincronizado evitarían que eso sucediera? –