JavaRush /Blog Java /Random-FR /Qu’est-ce que le blocage en Java ?
Alexey Smirnov
Niveau 29
Москва

Qu’est-ce que le blocage en Java ?

Publié dans le groupe Random-FR
Niveau de connaissances requis pour comprendre l'article : vous avez complété les quêtes Java Syntax et Java Core, et êtes désormais en train d'apprendre le Java Multithreading. Un blocage ou un blocage en Java ou un blocage est une erreur qui se produit lorsque les threads ont une dépendance cyclique sur une paire d'objets synchronisés. Imaginez qu'un thread entre dans le moniteur d'objets xet l'autre dans le moniteur d'objets y. Si un thread dans un objet xtente d'appeler une méthode synchronisée sur l'objet yet que l'objet ytente en même temps d'appeler une méthode synchronisée sur l'objet x, les threads resteront bloqués en attente. Qu’est-ce que l’impasse ?  - 1Vous trouverez ci-dessous un exemple tiré du didacticiel Java Docs sur un concept tel que le blocage. Où se produit le blocage des threads ici ?
public class Deadlock {
    static class Friend {
        private final String name;
        public Friend(String name) {
            this.name = name;
        }
        public String getName() {
            return this.name;
        }
        public synchronized void bow(Friend bower) {
            System.out.format("%s: %s" + "  has bowed to me!%n", this.name, bower.getName());
            bower.bowBack(this);
        }
        public synchronized void bowBack(Friend bower) {
            System.out.format("%s: %s"
                + " has bowed back to me!%n",
                this.name, bower.getName());
        }
    }

    public static void main(String[] args) {
        final Friend alphonse =
            new Friend("Alphonse");
        final Friend gaston =
            new Friend("Gaston");
        new Thread(new Runnable() {
            @Override
            public void run() {
               // System.out.println("Thread 1");
                alphonse.bow(gaston);
               // System.out.println("Th: gaston bowed to alphonse");
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
              //  System.out.println("Thread 2");
                gaston.bow(alphonse);
              //  System.out.println("2.gaston waiting alph bowed");
            }
        }).start();
    }
}
Il y a deux choses importantes à comprendre ici :
  1. Que fait exactement chacun des threads exécutés simultanément ?
  2. Quelles serrures sont utilisées ?
Commençons par la fin. Disons que vous avez créé deux objets de la classe Friend: alphonseet gaston. Chacun d'eux possède sa propre serrure. Ainsi, il existe deux de ces écluses : les gigolos et les gastons. Lorsqu'une méthode synchronisée d'un objet est entrée, son verrou est verrouillé, et lorsque la méthode est quittée, elle est libérée (ou déverrouillée). Parlons maintenant des fils. Appelons le premier thread Alphonse(avec une majuscule pour le distinguer de l'objet alphonse). Voici ce qu'il fait (appelons-le A, abréviation de Alphonse) :
A: alphonse.bow(gaston) — получает лок alphonse;
A: gaston.bowBack(alphonse) — получает лок gaston;
A: возвращается из обоих методов, тем самым освобождая лок.
Et voici ce que fait le fil en ce momentGaston :
G: gaston.bow(alphonse) — получает лок gaston;
G: alphonse.bowBack(gaston) — получает лок alphonse;
G: возвращается из обоих методов, тем самым освобождая лок.
Rassemblons maintenant ces données et obtenons la réponse. Les fils de discussion peuvent être entrelacés (c'est-à-dire que leurs événements se produiront) dans des ordres différents. Un blocage fonctionnera, par exemple, si l'ordre est le suivant :
A: alphonse.bow(gaston) — получает лок alphonse
G: gaston.bow(alphonse) — получает лок gaston
G: пытается вызвать alphonse.bowBack(gaston), но блокируется, ожидая лока alphonse
A: пытается вызвать gaston.bowBack(alphonse), но блокируется, ожидая лока gaston
Qu’est-ce que l’impasse ?  - 2
Dans ce cas, les deux threads sont bloqués et chacun attend que l’autre libère le verrou. Mais aucun d’entre eux ne le fera, car pour ce faire, ils doivent terminer leur méthode, et celle-ci est bloquée par un autre thread. Ils étaient donc coincés là où cela s'était produit deadlock. Cependant, un autre tissage est également possible, dans lequel l'un des fils aura le temps de se terminer avant que le second ne commence :
A: alphonse.bow(gaston) — получает лок alphonse
A: gaston.bowBack(alphonse) — получает лок gaston
A: возвращается из обоих методов, открывая оба лока
G: gaston.bow(alphonse) — получает лок gaston
G: alphonse.bowBack(gaston) — получает лок alphonse
G: возвращается из обоих методов, открывая оба лока
Dans ce cas, il n'y a pas de blocage mutuel des threads. Par exemple, une méthode a été ajoutée pour permettre à un autre thread d'avoir le temps de s'exécuter. Lorsque le résultat dépend de l'ordre des événements se produisant simultanément (ordre planifié ou vitesse d'exécution), un tel processus est appelé race condition en russe - « race condition ». Toutes les conditions de concurrence ne provoquent pas potentiellement une impasse, cependant, d'après mon expérience, seules les conditions de concurrence provoquent des impasses. Publié par: Dave Lillethun
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION