40 votes

Mot clé synchronisé imbriqué

J'ai ce code en Java:

     public void doSomeThing() {
        synchronized (this) {
            doSomeThingElse();
        }
    }
    public void doSomeThingElse() {
        synchronized (this) {
            // do something else
        }
    }
 

Ce code peut-il bloquer? Je veux dire, ce code peut-il attendre pour toujours?

51voto

Kissaki Points 4000

Comme le décrit la documentation Java relative au verrouillage réentrant :

un fil peut acquérir un verrou qu'il possède déjà

Le deuxième bloc synchronisé utilise le même verrou et sera donc toujours utilisable car le verrou a déjà été acquis dans la méthode externe.

Non, il n'y aura pas d'impasse.

8voto

fastcodejava Points 22174

Si un thread possède le verrou sur this , il entrera dans d'autres méthodes / blocs synchronized comme le couteau chaud dans du beurre.

3voto

Dennis Points 2323

En parallèle, un bloc que vous pouvez ré-acquérir un verrou que vous possédez déjà. La serrure fournisseur (ce) seront acquis par le premier thread pour entrer doSomething(). Puis, dans la doSomethingElse() la méthode de re-acquérir il.

La raison pour cela? Il n'y a rien à dire qu'il n'y a pas un autre thread entrer doSomethingElse d'ailleurs. Cela permettra d'éviter tout code de l'exécution du bloc en doSomething() jusqu'à ce que le thread dans doSomethingElse() a publié "ce".

Edit BTW, il peut bien sûr bloc... et il permet de bloquer n'importe quel thread qui n'est pas propriétaire de l'objet de synchronisation de l'exécution. Toutefois, il ne sera pas (posté) de blocage.

1voto

Gursel Koca Points 8541

Verrou déjà obtenu par le thread exécutant la méthode doSomething, ce thread peut donc exécuter la méthode doSomethingElse.

Vous avez besoin de deux objets de verrouillage pour créer une situation de blocage. Dans votre cas, il n'y en a qu'un, il est donc impossible de créer une impasse.

0voto

fluminis Points 1353

L'utilisation synchronisée dans les deux cas this ainsi si le bloc synchronisé dans doSomeThing est exécuté, vous avez déjà le verrou afin que vous puissiez exécuter la méthode doSomeThingElse.

Si votre code est si simple, cela équivaut à:

 public synchronized void doSomeThing() {
    doSomeThingElse();
}
public synchronized void doSomeThingElse() {
    // do something else
}
 

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