Betrachten Sie ein BlockingQueue
und ein paar Threads, die auf poll(long, TimeUnit)
warten (möglicherweise auch auf on take()
).
Jetzt ist die Warteschlange leer und es ist erwünscht, die wartenden Threads zu benachrichtigen, dass sie aufhören können zu warten. Das erwartete Verhalten ist, dass entweder null
zurückgegeben oder die deklarierte InterruptedException
ausgelöst wurde.
Object.notify()
funktioniert nicht für LinkedBlockingQueue
, da die Threads auf eine interne Sperre warten.
Irgendein einfacher Weg?
Javadoc für die BlockingQueue schlägt einen guten Weg vor:
Eine BlockingQueue ist nicht intrinsisch unterstützt jede Art von "Schließen" oder "Herunterfahren", um dies anzuzeigen Es werden keine weiteren Objekte hinzugefügt. Die Bedürfnisse und die Verwendung solcher Merkmale neigen dazu, zu sein implementierungsabhängig. Zum Beispiel Eine gemeinsame Taktik ist für Produzenten Fügen Sie spezielles End-of-Stream oder Gift ein Objekte, die interpretiert werden entsprechend, wenn sie von den Verbrauchern genommen werden.
Der herkömmliche Weg besteht darin, die Threads zu unterbrechen, aber das erfordert natürlich, dass sie Unterbrechungen richtig behandeln.
Dies bedeutet, dass InterruptedException
s korrekt um blockierende Methoden herum erfasst und gehandhabt wird, und das interrupted
-Flag sonst regelmäßig überprüft wird (und entsprechend reagiert).
In der API- oder Sprachspezifikation gibt es nichts, was die Unterbrechung einer spezifischen Abbruchsemantik bedeutet, aber in der Praxis ist die Verwendung von Unterbrechungen für alles außer Abbruch fragil und in größeren Anwendungen schwer aufrechtzuerhalten. [...]
Die Unterbrechung ist normalerweise der sinnvollste Weg, um die Löschung zu implementieren.
Sagt Java Concurrency in Practice in Abschnitt 7.1.1. Ein Beispiel für die korrekte Behandlung von Unterbrechungen, von demselben (dies ist ein Produzententhread, kein Verbraucher, aber dieser Unterschied ist im aktuellen Kontext vernachlässigbar):
%Vor% Eine alternative Lösung wäre, den Timeout-Parameter von poll
relativ niedrig zu setzen, so dass der Thread regelmäßig aufwacht und Unterbrechungen schnell genug bemerkt werden kann. Trotzdem glaube ich, dass es immer eine gute Übung ist, InterruptedException explizit entsprechend Ihrer spezifischen Thread-Cancellation-Richtlinie zu behandeln.
Ich würde sagen, dass etwas mit deinem Design nicht stimmt. Threads, die eine BlockingQueue verbrauchen, sollten nicht auf diese Weise unterbrochen werden. Wenn sie in einem regelmäßigen Intervall etwas anderes tun müssen (z. B. den Status einer Variablen überprüfen), während sie auch aus der Warteschlange konsumieren, sollten Sie die poll () -Methode mit einem entsprechend eingestellten Zeitlimit verwenden, so dass die beiden Aktionen verschachtelt werden können / p>
Tags und Links java concurrency blockingqueue