Warteschlange in Java ThreadPoolExecutor neu anordnen [duplizieren]

8

Ich habe einen ThreadPoolExecutor, der mit einer LinkedBlockingDequeue erstellt wurde, und ich möchte die zugrunde liegende Warteschlange bearbeiten, aber das Lesen in der Dokumentation macht mich sehr nervös.

  

Warteschlangenverwaltung

     

Die Methode getQueue () erlaubt den Zugriff auf die Arbeitswarteschlange zum Überwachen und Debuggen. Von der Verwendung dieser Methode für andere Zwecke wird dringend abgeraten. Zwei bereitgestellte Methoden, remove (java.lang.Runnable) und purge (), sind verfügbar, um bei der Speicherrückgewinnung zu helfen, wenn eine große Anzahl von Aufgaben in der Warteschlange abgebrochen wird.

Genauer gesagt möchte ich dazu in der Lage sein

  1. Überprüfen Sie die Warteschlange, um festzustellen, ob bereits ein Element vorhanden ist. Ich nehme an, das ist in Ordnung, da kein Sperren erforderlich sein sollte, um nur die Elemente in der Warteschlange anzuzeigen.
  2. Ich möchte die Warteschlange basierend auf einem bestimmten Signal neu anordnen. Dies kann offensichtlich mühsam sein. Ich habe mich gefragt, ob es einen bevorzugten Weg gibt, dies zu tun, damit ich die Warteschlange nicht für andere Zwecke durcheinander bringe.

Danke

    
Jon 20.09.2012, 17:55
quelle

1 Antwort

4

getQueue() gibt immer die genaue BlockingQueue<Runnable> zurück, die Sie an die ThreadPoolExecutor übergeben haben.

Die Sorge mit der Dokumentation ist, dass Sie leicht auf Probleme mit doppeltem Ausführen stoßen könnten, wenn Sie die Thread-Sicherheit von BlockingQueue nicht garantieren können. Wenn Sie PriorityBlockingQueue verwenden und nur remove und add (oder direkter offer ) verwenden, sind Sie sicher und können dies auch direkt von getQueue() aus tun.

Mit anderen Worten, jedes Mal, wenn Ihr Signal Ihnen sagt, dass sich die Runnable -Priorität geändert hat, sollten Sie remove it und das Ergebnis der Entfernung überprüfen ( true wenn entfernt) und nur wenn es war tatsächlich entfernt, dann sollten Sie es erneut hinzufügen. Sie können nicht garantieren, dass zwischen diesen Vorgängen nicht etwas abgerufen wird, aber Sie haben zumindest garantiert, dass Sie Runnable nicht doppelt ausführen, was leicht passieren könnte, wenn Sie mit contains - & gt; remove - & gt; add .

Entweder das, oder Sie können Ihre eigene Implementierung eines BlockingQueue schreiben, das ein Comparator verwendet (wie das PriorityBlockingQueue ), das die höchste Priorität findet, wenn es nach neuen Daten gefragt wird. Das klingt nach viel mehr Arbeit angesichts der verschiedenen beteiligten Schnittstellen.

    
pickypg 20.09.2012, 18:33
quelle

Tags und Links