Chaque fois qu'une question surgit sur SO à propos de la synchronisation Java, certaines personnes sont très désireuses de souligner que cela synchronized(this)
devrait être évité. Au lieu de cela, affirment-ils, un verrou sur une référence privée doit être préféré.
Certaines des raisons données sont:
- un code maléfique peut voler votre serrure (très populaire, celui-ci a également une variante "accidentellement")
- toutes les méthodes synchronisées dans la même classe utilisent exactement le même verrou, ce qui réduit le débit
- vous exposez (inutilement) trop d'informations
D'autres personnes, dont moi, soutiennent que synchronized(this)
c'est un idiome qui est beaucoup utilisé (également dans les bibliothèques Java), est sûr et bien compris. Il ne faut pas l'éviter car vous avez un bug et vous n'avez pas la moindre idée de ce qui se passe dans votre programme multithread. En d'autres termes: s'il est applicable, utilisez-le.
Je suis intéressé à voir des exemples du monde réel (pas de trucs de foobar) où éviter un verrouillage this
est préférable quand synchronized(this)
ferait également le travail.
Par conséquent: devez-vous toujours l'éviter synchronized(this)
et le remplacer par un verrou sur une référence privée?
Quelques informations supplémentaires (mises à jour au fur et à mesure des réponses):
- nous parlons de synchronisation d'instance
- les
synchronized
formes implicites ( méthodes) et explicites desynchronized(this)
sont considérées - si vous citez Bloch ou d'autres autorités sur le sujet, ne laissez pas de côté les parties que vous n'aimez pas (par exemple Java efficace, élément sur la sécurité des threads: il s'agit généralement du verrou sur l'instance elle-même, mais il y a des exceptions.)
- si vous avez besoin d'une granularité dans votre verrouillage autre que celle
synchronized(this)
fournie, alors cesynchronized(this)
n'est pas applicable donc ce n'est pas le problème