Deadlocks und Synchronisierte Methoden
Habe ich einen gefunden, der code auf Stack Overflow und ich dachte, es ist ziemlich ähnlich zu dem, was ich bin mit, aber ich verstehe immer noch nicht, warum das betreten einer Sackgasse. Das Beispiel wurde entnommen aus Deadlock-Erkennung in 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();
}
}
In diesem Fall, wenn der Deadlock () - Konstruktor aufgerufen wird, beginnt es sich wie ein Roter Faden. Wenn es dies tut, werden die run () - Methode aufgerufen. Es ruft b an.methodB(a), das ruft dann ein.last() nur drucken Sie eine Erklärung. Zur gleichen Zeit, ein.methodA(b) nennen würde.b.last(). Es gibt keine Kreuz-Abhängigkeiten auf jedes Objekt, und Sie sind nicht der Ausführung einer Methode gleichzeitig zu. Selbst wenn Sie es sind, die synchronisiert Stichwort anstehen hätte Sie, wäre es nicht? Aber wie kommen diese gelegentlich geben Sie einen deadlock zu? Es ist nicht die ganze Zeit, aber es würde manchmal geben Sie einen deadlock, das ist ziemlich unvorhersehbar. Was ist es, das bewirkt, dass dieser gehen in einen deadlock und workarounds?
InformationsquelleAutor Carven | 2011-06-07
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ist es möglich, dass die Ausführung dieser beiden Aussagen ist verwebte:
ausführen
a.methodA()
Thread 1 benötigen Sie die Sperre auf derA
Objekt.ausführen
b.methodB()
Thread 2 benötigen Sie die Sperre auf derB
Objekt.Für Thread 1
methodA()
dann aufrufen zu können sychronized-Methode auf dieb
Instanz, die es zu erhalten müssen Sie die Sperre aufb
gehalten, die von Thread 2, die bewirken, dass Thread 1 warten Sie, bis das lock freigegeben wird.Für Thread2 verzahnt ist
methodB()
zu können, rufen Sie die synchronisierte Methode auf diea
Instanz, die es zu erhalten müssen Sie die Sperre gehalten wird, aufa
von Thread 1 - die bewirkt, dass Thread 2 warten auch.Da jeder thread eine Sperre, dass der andere thread will, kann ein deadlock auftreten wird, wo keiner der beiden Threads ist in der Lage, um die Sperre, die es will, und weder thread Freigabe der sperren, die es hat halten.
Es ist wichtig zu verstehen, dass dieser code führt nicht zu einer deadlock-100% der Zeit, die Sie es ausführen - nur, wenn die vier entscheidenden Schritte (Thread1 hält die Sperre und versucht, Sie zu erhalten, B Thread 2 besitzt B die Sperre und versucht, Sie zu erhalten A) sind in einer bestimmten Reihenfolge ausgeführt. Führen Sie diesen code oft genug und damit ist vorprogrammiert, wenn.
wahrscheinlich könnten Sie Betten Sie ein Bild aus websequencediagrams.com oder yuml.mich
ja, das würde auch funktionieren, aber nicht so schön wie die Zeichnung direkt auf 😉
Gibt es eine Möglichkeit in Java, kann ich dieses problem verhindern? Ich bin versucht, zu denken, wie kann ich vermeiden, das deadlock-problem, aber es scheint sehr verwirrend, da Sie sowohl gelegentlich kommen zu einer situation, wo Sie automatisch einen warten. danke!
Ja - Argumentation über welche Arten von Synchronisierung ist notwendig, in Ihrem Programm, wie etwa die Verhinderung verschiedenen threads ändern die gleichen Daten in einem nicht-thread-sichere Weise. Sie müssen zuerst verstehen, was schlechte Dinge passieren können, wenn mehrere threads auf den gleichen Instanzen Ihrer Objekte, um zu wissen, wie um Nebenwirkungen zu vermeiden. Es gibt keine schnelle und einfache Lösung, und markieren alles
synchronized
nicht wirklich helfen - hast du wahrscheinlich nur gemacht, Ihr Programm single-threaded!InformationsquelleAutor matt b
synchronized
stellen eine Sperre auf die Objekt erworben werden müssen, bevor die Methoden oder codeblocks ausführen kann. Weil es sperrt alle Objekte, es ist ein unelegant-tool, das sieht manchmal ziemlich einfach zu benutzen, aber gibt Blockaden wie diese, in denen keine tatsächlichen bestritten Daten gelesen oder geschrieben werden.a.method(b)
sperrt diea
Objekt.b.method(a)
sperrt dieb
Objekt. Und keiner der beiden Threads von der Ausführung können weitere Berufungb.last()
odera.last()
, weil Sie beide warten auf die andere Sache zu release seine Sperre.lernen, wie man Programm Auger Programme richtig ist ein weites Feld für das Studium; der beste Rat, den ich gehört habe "Daten sperren, nicht code". Java ist
synchronized
macht es einfach, code-Sperre, aber das sperren bestimmter Daten-Objekten ist das mehr nützliches tool, das auf lange Sicht. Es ist in der Regel auch einfacher zu Grund zu sperren, die auf data, so können Sie erzwingen, eine Sperre Hierarchie, um zu verhindern, dass deadlocks.InformationsquelleAutor sarnold
Aufruf von methodA nicht (effektiv) lock(a) lock(b).
Wenn die Aufgabe wechselt dann und versucht methodB, es trifft lock(b), dann rechts.
InformationsquelleAutor david van brink