Ich bin neu in diesem Thema ... Ich benutze einen ThreadPoolExecutor erstellt mit Executors.newFixedThreadPool (10) und nachdem der Pool voll ist, beginne ich eine RejectedExecutionException zu bekommen. Gibt es eine Möglichkeit, den Executor zu "zwingen", den neuen Task in einen "Warte" -Status zu versetzen, anstatt ihn abzulehnen und ihn zu starten, wenn der Pool freigegeben wird?
Danke
Problem diesbezüglich Ссылка
Die Codezeile war Ссылка
Wenn Sie Executors.newFixedThreadPool(10);
verwenden, werden die Aufgaben in eine Warteschlange gestellt, und sie warten, bis ein Thread fertig ist.
Diese Methode ist
%Vor%Wie Sie sehen können, ist die verwendete Warteschlange unbegrenzt (was an sich schon ein Problem sein kann), aber das bedeutet, dass die Warteschlange niemals gefüllt wird und Sie niemals eine Ablehnung erhalten.
BTW: Wenn Sie CPU-gebundene Tasks haben, kann eine optimale Anzahl von Threads
sein %Vor%Eine Testklasse, die die Situation veranschaulichen könnte
%Vor%druckt
%Vor% Es ist sehr gut möglich, dass ein Thread exit
aufruft, was mStopped
auf false setzt und den Executor herunterfährt, aber:
while (!mStopped)
-Schleife und versucht, eine Aufgabe an den Executor zu senden, der von exit
heruntergefahren wurde.
while
gibt "true" zurück, weil die Änderung in " mStopped
" nicht sichtbar ist (Sie verwenden keine Form der Synchronisierung um dieses Flag). Ich würde vorschlagen:
mStopped
volatile Aufbauend auf früheren Vorschlägen können Sie eine Blockierungswarteschlange verwenden, um eine feste Größe ThreadPoolExecutor
zu erstellen. Wenn Sie dann Ihr eigenes RejectedExecutionHandler
angeben, das der blockierenden Warteschlange Aufgaben hinzufügt, verhält es sich wie beschrieben.
Hier ist ein Beispiel, wie Sie einen solchen Executor erstellen können:
%Vor%Wenn ich es richtig verstanden habe, haben Sie Ihren ThreadPool mit einer festen Anzahl von Threads erstellt, aber Sie haben möglicherweise mehr Aufgaben, um ihn an den Thread-Pool zu senden. Ich würde die keepAliveTime basierend auf der Anfrage berechnen und dynamisch setzen. Auf diese Weise hätten Sie RejectedExecutionException nicht.
Zum Beispiel
lang keepAliveTime = ((applications.size () * 60) / FIXED_NUM_OF_THREADS) * 1000; threadPoolExecutor.setKeepAliveTime (keepAliveTime, TimeUnit.MILLISECONDS);
wo die Anwendung eine Sammlung von Aufgaben ist, die jedes Mal anders sein kann.
Das sollte Ihr Problem lösen, wenn Sie wissen, wie lange die Aufgabe durchschnittlich dauert.
Tags und Links java multithreading threadpool threadpoolexecutor