Im Folgenden finden Sie einige häufig gestellte Thread-Pool-Fragen, die ich in Java-Interviews zusammengestellt habe, und ich werde sie jetzt mit Ihnen teilen.
(Teilen von Lernvideos: Java-Lehrvideo)
Was ist ein Thread-Pool?
Thread-Pool ist eine Form der Multi-Thread-Verarbeitung. Während der Verarbeitung werden Aufgaben an den Thread-Pool übermittelt und die Ausführung der Aufgabe wird vom Thread-Pool verwaltet.
Wenn für jede Anfrage ein Thread zur Verarbeitung erstellt wird, sind die Ressourcen des Servers bald erschöpft. Durch die Verwendung eines Thread-Pools kann die Anzahl der erstellten und zerstörten Threads verringert werden und mehrere Aufgaben ausgeführt werden.
Warum Thread-Pool verwenden?
Die Kosten für das Erstellen und Zerstören von Threads sind relativ hoch und diese Zeiten können länger sein als die Zeit für die Geschäftsabwicklung. Eine solche häufige Erstellung und Zerstörung von Threads in Verbindung mit Business-Worker-Threads verbraucht Systemressourcenzeit, was zu unzureichenden Systemressourcen führen kann. (Wir können den Prozess des Erstellens und Zerstörens von Threads entfernen)
Welche Rolle spielt der Thread-Pool?
Die Funktion des Thread-Pools besteht darin, die Anzahl der Ausführungsthreads im System zu begrenzen.
1. Erstellen Sie eine bestimmte Anzahl von Threads und legen Sie sie bei Bedarf aus dem Pool ab. Dies ist viel schneller als das Erstellen eines Thread-Objekts.
2. Um die Verwaltung zu erleichtern, können Sie Thread-Pool-Verwaltungscode schreiben, um die Threads im Pool einheitlich zu verwalten. Wenn das Programm beispielsweise gestartet wird, wird ihm die Arbeit zugewiesen. Wenn es gleichzeitig ist Es gibt 101 Anfragen, und die zusätzliche Anfrage kann in die Warteschlange gestellt werden, um Systemabstürze durch endlose Thread-Erstellung zu vermeiden.
Lassen Sie uns über mehrere gängige Thread-Pools und Verwendungsszenarien sprechen
1. newSingleThreadExecutor
Erstellen Sie einen Single-Thread-Thread-Pool, um Aufgaben auszuführen, und stellen Sie sicher, dass alle Aufgaben in der angegebenen Reihenfolge sind (FIFO). , LIFO, Priorität) Ausführung.
2. newFixedThreadPool
Erstellt einen Thread-Pool mit fester Länge, der die maximale Anzahl gleichzeitiger Threads steuern kann, die in der Warteschlange warten.
3. newCachedThreadPool
Erstellen Sie einen zwischenspeicherbaren Thread-Pool. Wenn die Länge des Thread-Pools den Verarbeitungsbedarf überschreitet, können inaktive Threads flexibel recycelt werden.
4. newScheduledThreadPool
Erstellen Sie einen Thread-Pool mit fester Länge, um die geplante und periodische Aufgabenausführung zu unterstützen.
Mehrere wichtige Parameter im Thread-Pool
corePoolSize ist die Anzahl der Kern-Threads im Thread-Pool. Diese Kern-Threads werden nur dann nicht recycelt, wenn sie nicht verwendet werden.
maximumPoolSize ist das, was im Thread-Pool untergebracht werden kann Anzahl der Threads
keepAliveTime ist die längste Zeit, die andere Threads außer dem Kern-Thread im Thread-Pool aufbewahrt werden können, da sie im Thread-Pool mit Ausnahme des Kern-Threads nicht gelöscht werden können, selbst wenn keine Aufgabe vorhanden ist eine Überlebenszeit, die die längste Leerlaufzeit bedeutet, die Nicht-Kern-Threads behalten können
util, eine Einheit zur Berechnung dieser Zeit.
workQueue ist eine Warteschlange. Aufgaben können in der Aufgabenwarteschlange gespeichert werden und auf ihre Ausführung warten. Sie implementiert das FIFIO-Prinzip (First In, First Out).
(Weitere verwandte Interviewfragen zum Teilen: Java-Interviewfragen und -antworten)
threadFactory ist eine Thread-Fabrik, die Threads erstellt.
Handler ist eine Ablehnungsstrategie. Wir können die Ausführung bestimmter Aufgaben verweigern, nachdem die Aufgaben erledigt sind.
Lassen Sie uns über die Denial-Strategie des Thread-Pools sprechen.
Wenn weiterhin Anforderungsaufgaben eingehen und das System sie zu diesem Zeitpunkt nicht verarbeiten kann, müssen wir eine Denial-of-Service-Strategie anwenden. Die RejectedExecutionHandler-Schnittstelle bietet die Möglichkeit für benutzerdefinierte Methoden zum Ablehnen der Aufgabenverarbeitung. In ThreadPoolExecutor sind vier Verarbeitungsstrategien enthalten.
AbortPolicy-Strategie: Diese Strategie löst direkt eine Ausnahme aus und verhindert, dass das System normal funktioniert.
CallerRunsPolicy-Richtlinie: Solange der Thread-Pool nicht geschlossen ist, führt diese Richtlinie die aktuell verworfene Aufgabe direkt im Aufrufer-Thread aus.
DiscardOleddestPolicy-Strategie: Diese Strategie verwirft die älteste Anforderung, also die auszuführende Aufgabe, und versucht erneut, die aktuelle Aufgabe zu übermitteln.
DiscardPolicy-Strategie: Diese Strategie verwirft stillschweigend Aufgaben, die ohne Verarbeitung nicht verarbeitet werden können.
Zusätzlich zu den vier von JDK standardmäßig bereitgestellten Ablehnungsstrategien können wir die Ablehnungsstrategie an unsere eigenen Geschäftsanforderungen anpassen. Die Anpassungsmethode ist sehr einfach, implementieren Sie einfach die RejectedExecutionHandler-Schnittstelle direkt.
Was ist der Unterschied zwischen Ausführen und Senden?
In der vorherigen Erklärung haben wir die Execute-Methode zum Ausführen von Aufgaben verwendet. Zusätzlich zur Execute-Methode gibt es auch eine Submit-Methode, mit der die von uns übermittelten Aufgaben ausgeführt werden können.
Was ist der Unterschied zwischen diesen beiden Methoden? In welchen Szenarien sind sie anwendbar? Lassen Sie uns eine einfache Analyse durchführen.
execute eignet sich für Szenarien, in denen Sie nicht auf den Rückgabewert achten müssen. Sie müssen den Thread nur zur Ausführung in den Thread-Pool werfen.
Die Submit-Methode eignet sich für Szenarien, in denen Sie auf den Rückgabewert achten müssen
Verwendungsszenarien von fünf Thread-Pools
newSingleThreadExecutor: Ein Thread-Pool mit einem Thread, der in Szenarien verwendet werden kann, in denen die sequentielle Ausführung garantiert werden muss und nur ein Thread ausgeführt wird.
newFixedThreadPool: Ein Thread-Pool mit fester Größe, der verwendet werden kann, um die Anzahl der Threads unter bekanntem Parallelitätsdruck zu begrenzen.
newCachedThreadPool: Ein Thread-Pool, der unendlich erweitert werden kann und sich besser für die Verarbeitung von Aufgaben mit relativ kurzer Ausführungszeit eignet.
newScheduledThreadPool: Ein Thread-Pool, der verzögert und geplant gestartet werden kann und sich für Szenarien eignet, die mehrere Hintergrundthreads zur Ausführung regelmäßiger Aufgaben erfordern.
newWorkStealingPool: Ein Thread-Pool mit mehreren Aufgabenwarteschlangen, der die Anzahl der Verbindungen reduzieren und Threads mit der aktuellen Anzahl verfügbarer CPUs für die parallele Ausführung erstellen kann.
Schließen Sie den Thread-Pool
Das Schließen des Thread-Pools kann durch Aufrufen von ShutdownNow und Shutdown-Methoden erreicht werden
ShutdownNow: Interrupt() für alle ausgeführten Aufgaben ausgeben, Ausführung stoppen, alle noch nicht gestarteten Aufgaben abbrechen und zu zurückkehren die Liste der Aufgaben, die noch nicht gestartet wurden.
shutdown: Wenn wir Shutdown aufrufen, akzeptiert der Thread-Pool keine neuen Aufgaben mehr, aber er beendet nicht zwangsweise Aufgaben, die übermittelt wurden oder ausgeführt werden.
Auswahl der Anzahl der Threads beim Initialisieren des Thread-Pools
Wenn die Aufgabe IO-intensiv ist, muss die Anzahl der Threads im Allgemeinen auf mehr als das Zweifache der Anzahl der CPUs eingestellt werden, um die Nutzung der CPU-Ressourcen zu maximieren.
Wenn die Aufgabe CPU-intensiv ist, muss die Anzahl der Threads im Allgemeinen nur durch Addition von 1 zur Anzahl der CPUs festgelegt werden. Mehr Threads können nur den Kontextwechsel erhöhen, aber nicht die CPU-Auslastung.
Das Obige ist nur eine Grundidee. Wenn Sie wirklich eine genaue Kontrolle benötigen, müssen Sie nach dem Online-Gehen immer noch die Anzahl der Threads und Warteschlangen im Thread-Pool beobachten.
Welche Art von Arbeitswarteschlangen gibt es im Thread-Pool? 1. ArrayBlockingQueue
ist eine begrenzte Blockierungswarteschlange, die auf einer Array-Struktur basiert. Diese Warteschlange sortiert Elemente nach dem FIFO-Prinzip (First In, First Out).
2. LinkedBlockingQueue
Eine Blockierungswarteschlange basierend auf einer verknüpften Listenstruktur. Diese Warteschlange sortiert Elemente nach FIFO (First In First Out) und der Durchsatz ist normalerweise höher als bei ArrayBlockingQueue. Die statische Factory-Methode Executors.newFixedThreadPool() verwendet diese Warteschlange
3, SynchronousQueue
Eine blockierende Warteschlange, die keine Elemente speichert. Jeder Einfügevorgang muss warten, bis ein anderer Thread den Entfernungsvorgang aufruft. Andernfalls wird der Einfügevorgang immer blockiert und der Durchsatz ist normalerweise höher als der LinkedBlockingQueue. Die statische Factory-Methode Executors.newCachedThreadPool verwendet diese Warteschlange.
4. PriorityBlockingQueue
Eine unendliche Blockierungswarteschlange mit Priorität.
Empfohlene Kurse:
Java-Einführungs-TutorialDas obige ist der detaillierte Inhalt vonJava-Interview-Thread-Pool. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!