222 votes

Verrouillage de méthode Java synchronisé sur un objet ou une méthode?

Si j'ai 2 méthodes synchronisées dans la même classe, mais que chacune accède à des variables différentes, 2 threads peuvent-ils accéder à ces 2 méthodes en même temps? Le verrou se produit-il sur l'objet ou est-il aussi spécifique que les variables de la méthode synchronisée?

Exemple:

 class X {

    private int a;
    private int b;

    public synchronized void addA(){
        a++;
    }

    public synchronized void addB(){
        b++;
    }

}
 

Deux threads peuvent-ils accéder à la même instance de classe X en exécutant x.addA( ) et x.addB() simultanément?

227voto

OscarRyz Points 82553

Si vous déclarez la méthode que synchonized (comme vous le faites en tapant public synchronized void addA()) vous synchroniser sur l' ensemble de l' objet, de sorte que deux threads accèdent à une autre variable à partir de ce même objet serait de bloquer les uns les autres de toute façon.

Si vous souhaitez synchroniser sur une seule variable à la fois, les deux fils de ne pas se bloquer les uns les autres, tandis que l'accès aux différentes variables, vous devez synchroniser sur eux séparément syncrhonized() blocs. Si a et b étaient des références d'objet, vous devez utiliser:

public void addA() {
    synchronized( a ) {
        a++;
    }
}
public void addB() {
    synchronized( b ) {
        b++;
    }
}

Mais depuis qu'ils sont primitives, vous ne pouvez pas le faire.

Je vous suggère d'utiliser AtomicInteger à la place:

import java.util.concurrent.atomic.AtomicInteger;
class X {
    AtomicInteger a;
    AtomicInteger b;
    public void addA(){
        a.incrementAndGet();
    }
    public void addB(){ 
        b.incrementAndGet();
    }
}

77voto

Yishai Points 42417

Syncronisé sur la déclaration de méthode est un sucre syntaxique pour ceci:

  public void addA() {
     syncronized (this) {
          a++;
     }
  }
 

Sur une méthode statique, c'est un sucre syntaxique pour ceci:

  ClassA {
     public static void addA() {
          syncronized(ClassA.class) {
              a++;
          }
 }
 

Je pense que si les concepteurs de Java savaient alors ce que l’on comprend maintenant en ce qui concerne la synchronisation, ils n’auraient pas ajouté le sucre syntaxique, car cela conduit le plus souvent à une mauvaise mise en œuvre de la concurrence.

14voto

Nathan Hughes Points 30377

La serrure est accessible sur l'objet, et non pas sur la méthode. Quelles sont les variables accessibles dans la méthode n'est pas pertinente.

L'ajout de "synchronisation" à la méthode signifie que le thread qui exécute le code doit acquérir le verrou sur l'objet avant de continuer. L'ajout de "static synchronized" signifie que le thread qui exécute le code doit acquérir le verrou sur l'objet de classe avant de continuer. Alternativement, vous pouvez placer le code dans un bloc comme ceci:

public void addA() {
    synchronized(this) {
        a++;
    }
}

de sorte que vous pouvez spécifier l'objet dont la fermeture doit être acquis.

Si vous voulez éviter le verrouillage de l'objet contenant, vous pouvez choisir entre:

  • à l'aide de blocs synchronisés qui spécifient les serrures différentes
  • faire a et b atomique (à l'aide de java.util.de façon concomitante.atomique)

3voto

dsmith Points 1610

Vous pouvez faire quelque chose comme ce qui suit. Dans ce cas, vous utilisez le verrou sur a et b pour synchroniser au lieu du verrou sur "this". Nous ne pouvons pas utiliser int parce que les valeurs primitives n'ont pas de verrou, nous utilisons donc Integer.

 class x{
   private Integer a;
   private Integer b;
   public void addA(){
      synchronized(a) {
         a++;
      }
   }
   public synchronized void addB(){
      synchronized(b) {
         b++;
      }
   }
}
 

0voto

AIQB Points 101

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