111 votes

Bloc synchronisé Java pour .class

Que signifie ce code java ? Obtiendra-t-il un verrouillage sur tous les objets de MyClass ?

synchronized(MyClass.class) {
   //is all objects of MyClass are thread-safe now ??
}

Et comment le code ci-dessus diffère de celui-ci :

synchronized(this) {
   //is all objects of MyClass are thread-safe now ??
}

156voto

Thomas Jung Points 17692

L'extrait synchronized(X.class) utilise l'instance de classe comme moniteur. Comme il n'existe qu'une seule instance de classe (l'objet représentant les métadonnées de la classe au moment de l'exécution), un seul thread peut se trouver dans ce bloc.

Avec synchronized(this) le bloc est gardé par l'instance. Pour chaque instance, un seul thread peut entrer dans le bloc.

synchronized(X.class) est utilisé pour s'assurer qu'il y a exactement un Thread dans le bloc. synchronized(this) garantit qu'il y a exactement un thread par instance. Le fait que cela rende le code réel du bloc thread-safe dépend de l'implémentation. Si l'on ne modifie que l'état de l'instance synchronized(this) est suffisant.

91voto

Jorn Points 5202

Pour ajouter aux autres réponses :

static void myMethod() {
  synchronized(MyClass.class) {
    //code
  }
}

est équivalent à

static synchronized void myMethod() {
  //code
}

et

void myMethod() {
  synchronized(this) {
    //code
  }
}

est équivalent à

synchronized void myMethod() {
  //code
}

23voto

David M Points 45808

Non, le premier obtiendra un verrou sur la définition de la classe de MyClass mais pas toutes les instances. Cependant, si elle est utilisée dans une instance, elle bloquera effectivement toutes les autres instances, puisqu'elles partagent une même définition de classe.

La seconde obtiendra un verrou sur l'instance actuelle seulement.

Quant à savoir si cela rend vos objets thread safe, c'est une question bien plus complexe - nous avons besoin de voir votre code !

0voto

user2635057 Points 19

Oui, il le fera (sur tout bloc/fonction synchronisé).

Je me pose cette question depuis quelques jours pour moi-même (en fait en kotlin). J'ai finalement trouvé une bonne explication et je veux la partager :

Le verrouillage au niveau de la classe empêche plusieurs threads d'entrer dans un bloc synchronisé dans n'importe laquelle de toutes les instances disponibles de la classe au moment de l'exécution. Cela signifie que si, au moment de l'exécution, il existe 100 instances de DemoClass, un seul thread sera en mesure d'exécuter demoMethod() dans l'une des instances à la fois, et toutes les autres instances seront verrouillées pour les autres threads.

Le verrouillage au niveau de la classe doit toujours être effectué pour rendre les données statiques thread safe. Comme nous savons que le mot-clé static associe les données des méthodes au niveau de la classe, il faut donc utiliser le verrouillage au niveau des champs statiques ou des méthodes pour le faire au niveau de la classe.

Plus pour remarquer pourquoi .classe . C'est juste parce que .class est équivalent à toute variable statique de classe similaire à :

private final static Object lock = new Object();

où le nom de la variable de verrouillage est classe et le type est Classe<T>

Lire la suite : https://howtodoinjava.com/java/multi-threading/object-vs-class-level-locking/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X