So geben Sie Threads, die auf eine BlockingQueue warten, sofort frei

8

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?

    
Joel Shemtov 22.07.2010, 07:56
quelle

3 Antworten

13

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.

    
unbeli 22.07.2010 08:33
quelle
5

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.

    
Péter Török 22.07.2010 08:15
quelle
1

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>     

S73417H 22.07.2010 08:23
quelle

Tags und Links