Deux threads peuvent-ils accéder à une méthode synchronisée en même temps?
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() {
public void run() { alphonse.bow(gaston); }
}).start();
new Thread(new Runnable() {
public void run() { gaston.bow(alphonse); }
}).start();
}
}
quand je lance ce programme, je suis sortie comme
Alphonse: Gaston a s'inclina devant moi!
Gaston: Alphonse a s'inclina devant moi!
Peut donc deux threads accèdent à une méthode synchronisée en même temps?
source d'informationauteur harish
Vous devez vous connecter pour publier un commentaire.
Méthodes d'Instance (comme ton exemple) sont synchronisés sur l'objet qui les contient. Dans ce cas, lorsque vous appelez
alphonse.bow(...)
vous êtes le verrouillage de laalphonse
objet.gaston.bow(...)
serruresgaston
.Il ya un couple de façons que vous pouvez obtenir plusieurs instances d'un objet de verrouillage sur le même objet.
Vous pourriez faire la méthode
static
etsynchronized
dans le cas où ils se trouveraient sur la classe de l'objet lui-même. Il y a un seul de ces objets par le chargeur de classes.Ils pourraient à la fois de verrouillage définies objet statique. Quelque chose comme:
Votre sortie pourrait être quelque chose comme ce qui suit:
gaston
fil (mai) début de la première et appelsbow(alphonse)
gaston
objet et sorties:Gaston: Alphonse has bowed to me!
alphonse.bowBack(this)
.alphonse
objet et sorties:Alphonse: Gaston has bowed back to me!
alphonse.bowBack(this)
sorties, le déverrouillage de laalphonse
objet.gaston.bow(alphonse)
sorties, le déverrouillage de lagaston
objet.gaston
fil des sorties.alphonse
fil (mai) début de la prochaine et appelsbow(gaston)
alphonse
objet et sorties:Alphonse: Gaston has bowed to me!
gaston.bowBack(this)
.gaston
objet et sorties:Gaston: Alphonse has bowed back to me!
gaston.bowBack(this)
sorties, le déverrouillage de lagaston
objet.alphonse.bow(gaston)
sorties, le déverrouillage de laalphonse
objet.Cela pourrait se produire dans un certain nombre de différents ordres. Le
alphonse
thread peut s'exécuter en premier, même si c'eststart()
méthode est appelée à une date ultérieure. La seule chose que les verrous de vous sauver de l'est de l'appel dealphonse.bow(...)
sialphonse.bowBack(...)
est actuellement en cours d'exécution. @User988052 souligné, car chaque thread serrures leur propre objet et puis essaie de verrouiller les autres, vous pouvez facilement obtenir une impasse.Oui et non:
Oui, si la méthode est appelée sur différents des instances de la classe.
Non, deux threads ne peuvent pas appeler simultanément méthodes synchronisées sur la même instance de la classe. C'est le cas même si les deux fils appel à différentes méthodes (tant que l'instance est le même).
Je n'ai pas regardé ton code en détail, mais je pense que je reconnais la exemple typique de la façon de créer un blocage.
Cependant, vous ne devez pas appeler juste une fois pour essayer de créer de l'impasse.
Créer des threads dans une boucle et il y a une très forte probabilité que vous trouverez votre blocage:
Noter que vous n'aurez pas de blocage de votre 2000 threads: seulement certains d'entre eux vont être dans l'impasse. Vous pouvez le vérifier en prenant un threadump de votre programme/JVM.
Comme décrit dans la Impasse Des Tutoriels qui est où ce code vient de ce code est généralement bloquer.
Avec le mot-clé synchronized vous prenez un verrou sur une instance pour une méthode d'instance ou de classe pour une méthode statique. Donc, ici, vous garantie qu'au plus un seul thread exécute arc ou bowBack sur une instance donnée à un moment donné (si un thread exécute bow aucun autre thread peut exécuter bowBack parce que les deux méthodes se synchroniser sur la même serrure)...
Encore un commentaire: que les verrous sont réentrant une fois qu'un thread a acquis une serrure, il peut saisir d'autres méthodes de synchronisation sur la même serrure.