ThreadPoolExecutor Fixed Thread Pool mit benutzerdefiniertem Verhalten

7

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 Ссылка

    
Simone Margaritelli 08.11.2012, 10:47
quelle

4 Antworten

19

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%     
Peter Lawrey 08.11.2012, 10:49
quelle
3

Es ist sehr gut möglich, dass ein Thread exit aufruft, was mStopped auf false setzt und den Executor herunterfährt, aber:

  • Ihr laufender Thread befindet sich möglicherweise in der Mitte der while (!mStopped) -Schleife und versucht, eine Aufgabe an den Executor zu senden, der von exit heruntergefahren wurde.
  • Die Bedingung in 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:

  • make mStopped volatile
  • Behandeln Sie den Fall, in dem der Executor in der Mitte der Schleife heruntergefahren wird (z. B. durch Abfangen von RejectedExecutionException oder wahrscheinlich besser: Beenden Sie Ihren Executor nach der while-Schleife, anstatt ihn in der Exit-Methode zu beenden) / li>
assylias 08.11.2012 11:08
quelle
2

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%     
andreer 25.09.2013 13:31
quelle
0

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.

    
Paresh Dhabalia 12.04.2016 20:44
quelle