Cada vez que surge una pregunta en SO sobre la sincronización de Java, algunas personas están muy ansiosas por señalar que se synchronized(this)
debe evitar. En cambio, afirman, se prefiere un bloqueo en una referencia privada.
Algunas de las razones dadas son:
- algún código maligno puede robar tu cerradura (muy popular este, también tiene una variante "accidentalmente")
- Todos los métodos sincronizados dentro de la misma clase utilizan exactamente el mismo bloqueo, lo que reduce el rendimiento
- estás (innecesariamente) exponiendo demasiada información
Otras personas, incluyéndome a mí, argumentan que synchronized(this)
es un idioma que se usa mucho (también en las bibliotecas de Java), es seguro y se entiende bien. No debe evitarse porque tiene un error y no tiene ni idea de lo que está sucediendo en su programa multiproceso. En otras palabras: si es aplicable, utilícelo.
Estoy interesado en ver algunos ejemplos del mundo real (sin cosas de foobar) en los que evitar un bloqueo this
es preferible cuando synchronized(this)
también haría el trabajo.
Por lo tanto: ¿siempre debe evitarlo synchronized(this)
y reemplazarlo con un candado en una referencia privada?
Alguna información adicional (actualizada a medida que se dan las respuestas):
- estamos hablando de sincronización de instancias
- ambos implícitos (
synchronized
métodos) y forma explícita desynchronized(this)
se consideran - Si cita a Bloch u otras autoridades sobre el tema, no omita las partes que no le gustan (por ejemplo, Java efectivo, elemento sobre seguridad de subprocesos: por lo general, es el bloqueo de la instancia en sí, pero hay excepciones).
- si necesita granularidad en su bloqueo que no sea el
synchronized(this)
proporcionado, entoncessynchronized(this)
no es aplicable, por lo que ese no es el problema