Wie kann ich eine synchronisierte Anweisung in Java unterbrechen?
-
21-09-2019 - |
Frage
Ich habe zwei Threads, die auf dem gleichen Objekt synchonize wollen. Thead A
muss Interrupt-Thread B
der Lage sein, wenn eine bestimmte Bedingung erfüllt ist. Hier einig Pseudo-Code von dem, was die beiden Fäden tun / tun soll.
A:
public void run()
{
while(true)
{
//Do stuff
synchronized(shared)
{
//Do more stuff
if(condition)
{
B.interrupt();
}
}
}
}
B:
public void run()
{
while(true)
{
try
{
//Do stuff
synchronized(shared)
{
//Do more stuff
}
}
catch(InterruptedException e)
{
continue;
}
}
}
Hier ist die Situation, die ich nicht lösen kann:
- Thread
A
packt die gemeinsam genutzte Ressource und macht ein paar Sachen. - Inzwischen Thema
B
erreicht den synchronisierten Block, und erwartet fürA
seine gemeinsame Ressource zu veröffentlichen. - Thread
A
, während Sachen zu tun, erkennt, dass Thread B nicht die gemeinsam genutzte Ressource haben sollte, und versucht, Interrupt-ThreadB
. Aber ThemaB
hat bereits die Punkte übertroffen, wo einInterruptedException
geworfen werden kann.
Meine Frage ist, gibt es eine Möglichkeit, einen Thread zu unterbrechen, während es wartet synchronized
auf etwas zu sein?
Lösung
Für diese Art der Sache, sollten Sie die Klassen in java.util.concurrent.locks
-. sie weit mehr Fähigkeiten, einschließlich unterbrechbare Schlösser
Edit:. Wenn Sie nicht diese Klassen verwenden können, dann schauen Sie sich JKFF Antwort - Ihre Anforderungen können mit dem wait()
/ notify()
mechnism erfüllt werden, aber es ist einfach subtiler Fehler einführen
Andere Tipps
Tatsächlich sollten Sie die Schlösser verwenden oder Ihr Material mit den Object.wait()
implementieren, Object.notify()
und Object.notifyAll()
Methoden (Schlösser werden mit ihnen tatsächlich umgesetzt). Vergessen Sie nicht, die so genannte ‚unechte Wakeups‘ zu handhaben (wait()
zurückkehren kann, auch wenn niemand genannt notify()
oder notifyAll()
, so dass es immer in einer Schleife aufgerufen werden soll, dass die Kontrollen, dass die Bedingung Sie warten erfüllt ist).
Nein, aber ReentrantLock.lockInterruptibly()
verhält sich ähnlich wie die primitive monitorenter
Anweisung und unterbrochen werden kann.