Was genau ist der Unterschied zwischen der Größe des Kernpools und der maximalen Poolgröße, wenn wir darüber sprechen ThreadPoolExecutor
?
Kann es anhand eines Beispiels erklärt werden?
java
asynchronous
threadpoolexecutor
user2568266
quelle
quelle
Antworten:
Aus diesem Blog-Beitrag :
quelle
allowCoreThreadTimeOut(boolean)
, mit der Core-Threads nach einer bestimmten Leerlaufzeit beendet werden können. Wenn Sie dies auf true setzen undcore threads
= setzen,max threads
kann der Thread-Pool zwischen 0 und 0 skalierenmax threads
.IF laufenden Threads> corePoolSize & <MaxPoolSize , dann einen neuen Thread erstellen , wenn Gesamt - Task - Queue voll und neue ist ankommt.
Formular doc: (Wenn mehr als corePoolSize, aber weniger als maximalPoolSize- Threads ausgeführt werden, wird nur dann ein neuer Thread erstellt, wenn die Warteschlange voll ist.)
Nehmen Sie nun ein einfaches Beispiel:
Hier ist 5 die corePoolSize - bedeutet, dass Jvm für die ersten 5 Aufgaben einen neuen Thread für eine neue Aufgabe erstellt. und andere Aufgaben werden der Warteschlange hinzugefügt, bis die Warteschlange voll ist (50 Aufgaben).
10 ist die maxPoolSize - JVM kann maximal 10 Threads erstellen. Bedeutet, wenn bereits 5 Aufgaben / Thread ausgeführt werden und die Warteschlange mit 50 ausstehenden Aufgaben voll ist und eine weitere neue Anforderung / Aufgabe in der Warteschlange eintrifft, erstellt JVM einen neuen Thread mit bis zu 10 (Gesamtzahl der Threads = vorherige 5 + neue 5) ;;
new ArrayBlockingQueue (50) = ist eine Gesamtgröße der Warteschlange - es können 50 Aufgaben in die Warteschlange gestellt werden.
Sobald alle 10 Threads ausgeführt werden und eine neue Aufgabe eintrifft, wird diese neue Aufgabe abgelehnt.
Regeln zum internen Erstellen von Threads durch SUN:
Wenn die Anzahl der Threads geringer als corePoolSize ist, erstellen Sie einen neuen Thread, um eine neue Aufgabe auszuführen.
Wenn die Anzahl der Threads gleich (oder größer als) der corePoolSize ist, stellen Sie die Aufgabe in die Warteschlange.
Wenn die Warteschlange voll ist und die Anzahl der Threads geringer als maxPoolSize ist, erstellen Sie einen neuen Thread, in dem Aufgaben ausgeführt werden sollen.
Wenn die Warteschlange voll ist und die Anzahl der Threads größer oder gleich maxPoolSize ist, lehnen Sie die Aufgabe ab.
Hoffe, das ist HelpFul .. und bitte korrigiere mich, wenn ich falsch liege ...
quelle
Aus dem Dokument :
Außerdem:
quelle
Wenn Sie eine
ThreadPoolExecutor
manuell erstellen möchten, anstatt dieExecutors
Factory-Klasse zu verwenden, müssen Sie eine mit einem ihrer Konstruktoren erstellen und konfigurieren. Der umfangreichste Konstruktor dieser Klasse ist:Wie Sie sehen können, können Sie Folgendes konfigurieren:
Begrenzen der Anzahl der Aufgaben in der Warteschlange
Die Begrenzung der Anzahl der gleichzeitig ausgeführten Aufgaben und die Größe Ihres Thread-Pools stellt einen großen Vorteil für Ihre Anwendung und ihre Ausführungsumgebung in Bezug auf Vorhersagbarkeit und Stabilität dar: Eine unbegrenzte Thread-Erstellung erschöpft möglicherweise die Laufzeitressourcen und Ihre Anwendung kann dies zur Folge haben , schwerwiegende Leistungsprobleme, die sogar zu Instabilität der Anwendung führen können.
Dies ist eine Lösung für nur einen Teil des Problems: Sie begrenzen die Anzahl der ausgeführten Aufgaben, aber nicht die Anzahl der Jobs, die für die spätere Ausführung gesendet und in die Warteschlange gestellt werden können. Bei der Anwendung tritt später eine Ressourcenknappheit auf, die jedoch möglicherweise auftritt, wenn die Übermittlungsrate konstant über der Ausführungsrate liegt.
Die Lösung für dieses Problem lautet: Bereitstellen einer Blockierungswarteschlange für den Executor, um die wartenden Aufgaben zu speichern. Wenn die Warteschlange voll ist, wird die übermittelte Aufgabe "abgelehnt". Das
RejectedExecutionHandler
wird aufgerufen, wenn eine Aufgabenübermittlung abgelehnt wird, und deshalb wurde das abgelehnte Verb im vorherigen Element zitiert. Sie können Ihre eigene Ablehnungsrichtlinie implementieren oder eine der vom Framework bereitgestellten integrierten Richtlinien verwenden.Die Standard-Ablehnungsrichtlinien lassen den Executor a auslösen
RejectedExecutionException
. Mit anderen integrierten Richtlinien können Sie jedoch:quelle
Quelle
Die Regeln für die Größe von a
ThreadPoolExecutor's
Pools werden im Allgemeinen falsch verstanden, da sie nicht so funktionieren, wie Sie es sich vorstellen oder wie Sie es möchten.Nehmen Sie dieses Beispiel. Die Größe des Start-Thread-Pools beträgt 1, die Größe des Kernpools 5, die maximale Poolgröße 10 und die Warteschlange 100.
So geht's: Wenn Anfragen in Threads eingehen, werden bis zu 5 erstellt, dann werden Aufgaben zur Warteschlange hinzugefügt, bis sie 100 erreicht. Wenn die Warteschlange voll ist, werden neue Threads bis zu 5 erstellt
maxPoolSize
. Sobald alle Threads verwendet werden und die Warteschlange voll ist, werden Aufgaben abgelehnt. Wenn sich die Warteschlange verringert, verringert sich auch die Anzahl der aktiven Threads.Vom Benutzer erwartete Art und Weise: Wenn Anforderungen in Threads eingehen, werden bis zu 10 erstellt, und Aufgaben werden der Warteschlange hinzugefügt, bis sie 100 erreicht und an diesem Punkt abgelehnt werden. Die Anzahl der Threads wird maximal umbenannt, bis die Warteschlange leer ist. Wenn die Warteschlange leer ist, sterben die Threads ab, bis sie
corePoolSize
übrig sind.Der Unterschied besteht darin, dass die Benutzer die Poolgröße früher erhöhen und die Warteschlange kleiner machen möchten, während die Sun-Methode die Poolgröße klein halten und erst erhöhen möchte, wenn die Last zu groß wird.
Hier sind die Regeln von Sun für die Thread-Erstellung in einfachen Worten:
corePoolSize
, erstellen Sie einen neuen Thread, um eine neue Aufgabe auszuführen.corePoolSize
, stellen Sie die Aufgabe in die Warteschlange.maxPoolSize
, erstellen Sie einen neuen Thread, in dem Aufgaben ausgeführt werden.maxPoolSize
, lehnen Sie die Aufgabe ab. Das lange und das kurze daran ist, dass neue Threads nur erstellt werden, wenn die Warteschlange voll ist. Wenn Sie also eine unbegrenzte Warteschlange verwenden, wird die Anzahl der Threads nicht überschrittencorePoolSize
.Eine ausführlichere Erklärung finden Sie im Pferdemund:
ThreadPoolExecutor
API-Dokumentation.Es gibt einen wirklich guten Forumsbeitrag, der Ihnen zeigt, wie das
ThreadPoolExecutor
mit Codebeispielen funktioniert: http://forums.sun.com/thread.jspa?threadID=5401400&tstart=0Weitere Informationen: http://forums.sun.com/thread.jspa?threadID=5224557&tstart=450
quelle
Die Definition der Begriffe Corepoolsize und Maxpoolsize finden Sie im Javadoc. http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html
Der obige Link hat die Antwort auf Ihre Frage. Nur um es klar zu machen. Die Anwendung erstellt weiterhin Threads, bis sie die corePoolSize erreicht. Ich denke, die Idee hier ist, dass diese vielen Themen ausreichen sollten, um den Zufluss von Aufgaben zu bewältigen. Wenn eine neue Aufgabe kommt, nachdem die corePoolSize-Threads erstellt wurden, werden die Aufgaben in die Warteschlange gestellt. Sobald die Warteschlange voll ist, erstellt der Executor neue Threads. Es ist eine Art Ausgleich. Im Wesentlichen bedeutet dies, dass der Zufluss von Aufgaben mehr ist als die Verarbeitungskapazität. Executor erstellt also erneut neue Threads, bis die maximale Anzahl von Threads erreicht ist. Auch hier werden neue Threads erstellt, wenn die Warteschlange voll ist.
quelle
Gute Erklärung in diesem Blog:
Illustration
Ausgabe :
quelle
Aus dem Buch Java Concurency Essentials :
CorePoolSize : Der ThreadPoolExecutor verfügt über ein Attribut corePoolSize, das bestimmt, wie viele Threads gestartet werden, bis neue Threads erst gestartet werden, wenn die Warteschlange voll ist
MaximumPoolSize : Dieses Attribut bestimmt, wie viele Threads maximal gestartet werden. Sie können dies auf Integer setzen. MAX_VALUE, um keine obere Grenze zu haben
quelle
java.util.concurrent.ThreadPoolExecutor
quelle
Das Verständnis des internen Verhaltens
ThreadPoolExecutor
beim Einreichen einer neuen Aufgabe hat mir geholfen zu verstehen, wiecorePoolSize
und wie sich diesemaximumPoolSize
unterscheiden.Lassen:
N
die Anzahl der Threads im Pool sein ,getPoolSize()
. Aktive Threads + Leerlauf-Threads.T
Die Anzahl der Aufgaben, die an den Executor / Pool gesendet werden.C
die Kernpoolgröße sein ,getCorePoolSize()
. Wie viele Threads können höchstens pro Pool für die eingehenden Aufgaben erstellt werden, bevor neue Aufgaben in die Warteschlange gestellt werden .M
die maximale Poolgröße sein ,getMaximumPoolSize()
. Maximale Anzahl von Threads, die der Pool zuweisen kann.Verhalten von
ThreadPoolExecutor
in Java beim Senden einer neuen Aufgabe:N <= C
den inaktiven Threads wird nicht die neue eingehende Aufgabe zugewiesen, sondern ein neuer Thread wird erstellt.N > C
und wenn es freie Threads gibt, wird dort eine neue Aufgabe zugewiesen.N > C
und wenn KEINE Leerlauf-Threads vorhanden sind, werden neue Aufgaben in die Warteschlange gestellt. HIER KEIN NEUES GEWINDE ERSTELLT.M
. WennM
erreicht, lehnen wir die Aufgaben ab. Was hier nicht wichtig ist, ist, dass wir keine neuen Threads erstellen, bis die Warteschlange voll ist!Quellen:
Beispiele
Beispiel mit
corePoolSize = 0
undmaximumPoolSize = 10
mit einer Warteschlangenkapazität von50
.Dies führt zu einem einzelnen aktiven Thread im Pool, bis die Warteschlange 50 Elemente enthält.
Beispiel mit
corePoolSize = 10
undmaximumPoolSize = 10
mit einer Warteschlangenkapazität von50
.Dies führt zu 10 aktiven Threads im Pool. Wenn die Warteschlange 50 Elemente enthält, werden Aufgaben abgelehnt.
quelle