Les blocages et les méthodes Synchronisées
J'ai trouvé un code sur un Débordement de Pile et j'ai pensé que c'est assez similaire à ce que je suis confronté mais je ne comprends toujours pas pourquoi ce serait s'engager dans une impasse. L'exemple est tiré de La détection de blocage en Java:
Class A
{
synchronized void methodA(B b)
{
b.last();
}
synchronized void last()
{
System.out.println(“ Inside A.last()”);
}
}
Class B
{
synchronized void methodB(A a)
{
a.last();
}
synchronized void last()
{
System.out.println(“ Inside B.last()”);
}
}
Class Deadlock implements Runnable
{
A a = new A();
B b = new B();
//Constructor
Deadlock()
{
Thread t = new Thread(this);
t.start();
a.methodA(b);
}
public void run()
{
b.methodB(a);
}
public static void main(String args[] )
{
new Deadlock();
}
}
Dans ce cas, lorsque le Blocage() constructeur est appelé, il commence lui-même comme un fil. Quand il fait cela, la méthode run() est invoquée. Il va appeler b.methodB(a), qui appelle une.last() il suffit d'imprimer une déclaration. Dans le même temps, une.methodA(b) b.last(). Il n'y a pas de croix dépendances sur n'importe quel objet et ils ne sont pas l'exécution d'une méthode à une même trop de temps. Même si elles le sont, la synchronisation de mot-clé serait la file d'attente, ne serait-il pas? Mais comment se fait ce serait parfois entrer dans une impasse? Il n'est pas tout le temps mais qu'il serait parfois entrer dans une impasse, ce qui est tout à fait imprévisible. Qu'est-ce qui provoque ce pour aller dans une impasse et les solutions de contournement?
OriginalL'auteur Carven | 2011-06-07
Vous devez vous connecter pour publier un commentaire.
Il est possible que l'exécution de ces deux déclarations est entrelacée:
pour exécuter
a.methodA()
, 1 Fil aurez besoin d'obtenir un verrou sur laA
objet.pour exécuter
b.methodB()
, le Thread 2 aurez besoin d'obtenir un verrou sur laB
objet.Pour le Thread 1
methodA()
pour ensuite être en mesure d'appeler le sychronized méthode sur lab
exemple, il sera nécessaire d'obtenir le verrou surb
organisé par le Thread 2, ce qui va provoquer le Thread 1 à attendre jusqu'à ce que le verrou est libéré.Pour Thread2 de
methodB()
pour être en mesure d'appeler la méthode synchronisée sur lea
exemple, il sera nécessaire d'obtenir le verrou détenu sura
par le Thread 1 - qui va provoquer le Thread 2 à attendre.Depuis, chaque thread est le maintien d'un verrou que l'autre thread veut, un blocage se produire dans les cas où ni le thread est en mesure d'obtenir le verrou qu'il veut, et aucun thread libère les verrous qu'il ne tenir.
Il est important de comprendre que ce code ne sera pas produire un blocage 100% du temps de l'exécuter uniquement lorsque les quatre étapes cruciales (Thread1 est titulaire d'Un verrouillage et essaie d'obtenir B, le Thread 2 détient B de verrouillage et essaie d'obtenir Un) sont exécutées dans un certain ordre. Exécutez ce code assez de temps et que l'ordre est lié à arriver.
vous pourriez probablement intégrer une image à partir de websequencediagrams.com ou yuml.- moi
oui, ce serait trop de travail, mais pas aussi beau que le dessin directement sur 😉
Est-il possible en Java que je peux éviter ce problème? Je suis en train de réfléchir à comment je peux éviter ce problème de blocage, mais il semble très confus car ils seront tous les deux à l'occasion d'une situation où ils sont automatiquement attendre les uns des autres. merci!
Oui raisonnement au sujet de quels types de synchronisation est nécessaire dans votre programme, tels que la prévention des différents threads de modifier les mêmes données dans un non thread-safe. Vous devez d'abord comprendre ce que les mauvaises choses peuvent se produire si plusieurs threads accèdent à la même instances de vos objets, afin de savoir comment éviter les effets secondaires. Il n'y a pas de solution rapide et facile, et le marquage tout
synchronized
n'aide pas vraiment, vous avez probablement juste fait votre programme mono-thread!OriginalL'auteur matt b
synchronized
place un verrou sur la objet qui doit être acquis avant l'méthodes ou codeblocks peut exécuter. Parce qu'il verrouille ensemble des objets, c'est un peu sophistiqué outil qui parfois semble assez facile à utiliser, mais qui donne des blocages comme cela, où aucune attaqué des données sont lues ou écrites.a.method(b)
verrouille lea
objet.b.method(a)
verrouille leb
objet. Et ni l'exécution du thread pouvez continuer à appelerb.last()
oua.last()
, parce qu'ils sont tous les deux en attente pour l'autre objet pour libérer le verrou.apprendre comment le programme de formation professionnelle concurrent correctement est un vaste champ d'étude; le meilleur conseil que j'ai entendu, c'est "de verrouillage des données, pas de code". Java est
synchronized
facilite le code de verrouillage, mais de verrouillage spécifique des objets de données est l'outil plus utile que, dans le long terme. Généralement, il est également plus facile de raisonner sur des verrous sur les , de sorte que vous pouvez imposer une hiérarchie de verrouillage, pour éviter les blocages.OriginalL'auteur sarnold
Appel methodA (effectivement) de verrouillage(a), de verrouillage(b).
Si le groupe de commutateurs et tend methodB, il touche de verrouillage(b) à droite, puis.
OriginalL'auteur david van brink