150 votes

Méthodes statiques synchronisées de Java : verrouillage sur un objet ou une classe

La documentation Java dit :

Il n'est pas possible que deux invocations de méthodes synchronisées sur le même ordinateur puissent avoir lieu. même objet.

Qu'est-ce que cela signifie pour une méthode statique ? Puisqu'une méthode statique n'a pas d'objet associé, le mot-clé synchronisé se verrouillera-t-il sur la classe, au lieu de l'objet ?

2voto

Une méthode statique a également un objet associé. Elle appartient au fichier Class.class de la boîte à outils JDK. Lorsque le fichier .class est chargé dans la ram, la Class.class crée une instance de celui-ci appelée objet modèle.

Par exemple, lorsque vous essayez de créer un objet à partir d'une classe de client existante, par exemple

Customer c = new Customer();

La classe Customer.class se charge dans la RAM. À ce moment-là, Class.class dans la boîte à outils JDK crée un objet appelé objet modèle et charge la classe Customer.class dans cet objet modèle. Les membres statiques de la classe Customer.class deviennent des attributs et des méthodes dans cet objet modèle.

Ainsi, une méthode ou un attribut statique possède également un objet

2voto

jWeaver Points 4191

Les exemples ci-dessous donnent plus de clarté entre le verrouillage de classe et d'objet, en espérant que l'exemple ci-dessous aidera d'autres personnes également :)

Par exemple, nous avons les méthodes suivantes : l'une acquiert la classe et l'autre le verrou de l'objet :

public class MultiThread {

    public static synchronized void staticLock() throws InterruptedException {
        for (int i = 0; i < 10; i++) {
            Thread.sleep(100);
            System.out.println(Thread.currentThread().getName() + " " + i);
        }
    }

    public synchronized void objLock() throws InterruptedException {
        for (int i = 0; i < 10; i++) {
            Thread.sleep(100);
            System.out.println(Thread.currentThread().getName() + " " + i);
        }
    }
}

Donc, maintenant nous pouvons avoir les scénarios suivants :

  1. Lorsque des fils utilisant même objet essaie d'accéder objLock OU staticLock en même temps (c'est-à-dire que les deux threads essaient d'accéder à la même méthode)

    Thread-0 0
    Thread-0 1
    Thread-0 2
    Thread-0 3
    Thread-0 4
    Thread-1 0
    Thread-1 1
    Thread-1 2
    Thread-1 3
    Thread-1 4
  2. Lorsque des fils utilisant même objet essaie d'accéder staticLock y objLock méthodes en même temps (essaie d'accéder à des méthodes différentes)

    Thread-0 0
    Thread-1 0
    Thread-0 1
    Thread-1 1
    Thread-0 2
    Thread-1 2
    Thread-1 3
    Thread-0 3
    Thread-0 4
    Thread-1 4
  3. Lorsque des fils utilisant Objet différent essaie d'accéder staticLock méthode

    Thread-0 0
    Thread-0 1
    Thread-0 2
    Thread-0 3
    Thread-0 4
    Thread-1 0
    Thread-1 1
    Thread-1 2
    Thread-1 3
    Thread-1 4
  4. Lorsque des fils utilisant Objet différent essaie d'accéder objLock méthode

    Thread-0 0
    Thread-1 0
    Thread-0 1
    Thread-1 1
    Thread-0 2
    Thread-1 2
    Thread-1 3
    Thread-0 3
    Thread-0 4
    Thread-1 4

0voto

Pragya Points 1

Pour ceux qui ne sont pas familiers, les méthodes synchronisées statiques sont verrouillées sur la classe de l'objet, par exemple String.class pour la classe des chaînes de caractères, tandis que les méthodes synchronisées d'instance sont verrouillées sur l'instance actuelle de l'objet désigné par le mot clé "this" en Java. Comme ces deux objets sont différents, ils ont des verrous différents. Ainsi, lorsqu'un thread exécute une méthode synchronisée statique, l'autre thread en Java n'a pas besoin d'attendre le retour de ce thread, mais il acquiert un verrou distinct appelé byte .class literal et entre dans la méthode synchronisée statique.

-4voto

Iurii Points 1

Si yura a ça :

public class C1 {
    public static String STRIN1;
}

Vous devez le convertir en :

public class C1 {
    private static String STRIN1;
    private static Object SYNC_STRING1 = new Object();

    public static String getSTRING1(){
        synchronized (SYNC_STRING1) {
               return STRIN1;
        }
    }

    public static String setSTRING1(String newSTRIN1){
        synchronized (SYNC_STRING1) {
               STRIN1 = newSTIRNG1;
        }
    }
}

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