Der traditionelle ThreadPoolExecutor verwendet eine gelieferte BlockingQueue, um Elemente nur dann in die Warteschlange zu stellen, wenn für die eingehenden Aufgaben keine leeren Kernthreads verfügbar sind. Wenn es leere Kern-Threads gibt, versucht der Executor, die Threads den eingehenden Aufgaben direkt zuzuweisen.ThreadPoolExecutor mit erzwingender Warteschlange
Ich möchte ein etwas anderes Verhalten. Ich möchte, dass alle Aufgaben an die BlockingQueue und den Executor-Service übergeben werden, um nur Aufgaben aus der Warteschlange abzufragen.
Ich habe meine eigene Implementierung der BlockingQueue, die Elemente in Poll() basierend auf einer Überprüfung liefern (überprüfen Sie die Geschäftslogik für die Verarbeitung der Aufgaben), wenn die Prüfung fehlschlägt werden die Elemente nicht in der Umfrage (). Ich glaube, ThreadPoolExecutor ist bereits mit der Annahme implementiert, dass poll(), das null zurückgibt, nicht unbedingt bedeutet, dass die Warteschlange leer ist.
Mir ist ein Problem mit diesem Modell bekannt. Die Kern-Threads im traditionellen ThreadPoolExecutor werden nur erstellt, wenn Tasks über die execute() -Methode an den Executor übergeben werden. Wenn ich die Methode execute() überschreibe, um Aufgaben direkt in die BlockingQueue einzuordnen, werden die Kernthreads möglicherweise nicht erstellt. Ich kann dieses Problem umgehen, indem ich die Core-Threads vorstelle und sie nicht auf Timeout setze, damit die Kern-Threads immer am Leben sind. Ich muss auch überprüfen, dass die Anzahl der Kern Threads nicht mit 0 konfiguriert ist.
Wird dieses Modell funktionieren? Fehle ich, um mit einem Fall umzugehen? Ihre Gedanken.
(1) Dies sind asynchrone Verarbeitung. Ich möchte keine Elemente löschen, wenn die Überprüfung fehlschlägt, sie aber für einige Zeit in eine Warteschlange stellen und die Verarbeitung versuchen soll. (2) Ich muss die Überprüfung in einer Schleife durchführen (eine Busy-Wartezeit) und alle aktiven Threads sind beschäftigt, warten, um die Überprüfung durchzuführen. Bei der Planung in einer Warteschlange und deren Verwendung wird nur der Scheduler-Thread von threadPool verwendet, um die Überprüfung als Teil der Abfrage durchzuführen, die ohnehin in einer Schleife ausgeführt wird und die Warteschlange unendlich abfragt. Hinweis: Meine Überprüfung ist für alle Aufgaben gleich (z. B. den Zustand einer zugrunde liegenden Ressource, die für alle Aufgaben gemeinsam ist) –
Die Methode runWorker() hat eine komplizierte Logik, ruft aber getTask() auf und diese Methode blockiert in der Warteschlange bis sie eine Aufgabe zurückgibt, wird durch das Zurückgeben von null aus der Warteschlange der Arbeiter gestoppt - Sie haben angenommen, dass es anders ist. Das ist keine gute Idee, wie kann ich es dir sagen? Bitte machen Sie Ihr Leben oder das Leben anderer Entwickler, die mit Ihnen arbeiten, nicht zu einem Albtraum - dieser Code wird Sie sehr hart beissen. Denken Sie stattdessen lieber darüber nach, wie Sie bestehende Standardmechanismen nutzen können, um Ihr Ziel zu erreichen. Zur Inspiration lesen Sie ein Buch Java Concurrency in Practice. –