Was ist ein Fadenpool
Ein Thread -Pool ist eine Sammlung von Threads, die in einem oder mehreren Threads mehrere Anwendungslogik [Schleifenausführung].
Im Allgemeinen haben Threadpools die folgenden Teile:
Ein oder mehrere Threads, die die Hauptaufgabe erledigen.
Management -Threads, die zum Planungsmanagement verwendet werden.
Die Task -Warteschlange musste ausgeführt werden.
Die Funktion des Threadpools:
Die Funktion eines Threadpools besteht darin, die Anzahl der im System ausgeführten Threads zu begrenzen.
Abhängig von der Systemumgebung kann die Anzahl der Threads automatisch oder manuell eingestellt werden, um den besten Betriebseffekt zu erzielen. Weniger Systemressourcen werden verschwendet und mehr Systemstaus ist nicht hoch. Verwenden Sie einen Thread -Pool, um die Anzahl der Threads zu steuern, und andere Threads warten in der Linie. Nachdem eine Aufgabe ausgeführt wurde, wird die erste Aufgabe aus der Warteschlange übernommen, um die Ausführung zu starten. Wenn in der Warteschlange kein Wartevorgang vorhanden ist, wartet diese Ressource des Thread -Pools. Wenn eine neue Aufgabe ausgeführt werden muss und im Thread -Pool wartende Worker -Threads vorhanden sind, kann sie ausgeführt werden. Andernfalls wird die wartende Warteschlange eingetragen.
Thread Pool selbst implementieren
Basierend auf dem obigen Verständnis des Threadpools schreiben wir unseren eigenen einfachen Thread -Pool:
Einfache Thread -Pool -Schnittstelle:
öffentliche Schnittstelle Threadpool <Job erweitert Runnable> {// eine Aufgabe ausführen (Job), dieser Job muss Runnable void Execute (Job Job) implementieren; // Schließen Sie den Fadenpool void schaltdown (); // Erhöhen Sie den Worker -Thread, dh den Thread, der zur Ausführung der Task -Addworker (int num) verwendet wird. // den Worker -Thread -Leere reduzieren (int num); // Erhalten Sie die Anzahl der Aufgaben, die darauf warten, void GetJobsize ();};};Der Kunde kann den Auftrag über die Ausführungsmethode (Job) für die Ausführung an den Thread -Pool senden, und der Kunde muss nicht darauf warten, dass der Job überhaupt ausgeführt wird. Zusätzlich zur Ausführungsmethode (Job) bietet die Thread -Pool -Schnittstelle Methoden zum Erhöhen/Verringern von Arbeitsthreads und zum Schließen von Threadpools. Jeder Kunde gibt einen Job ein, der eine Arbeitswarteschlange eingibt und auf die Bearbeitung des Worker -Threads wartet.
Die Standardimplementierung der Thread -Pool -Schnittstelle
öffentliche Klasse Standardthreadpool <Job erweitert Runnable> implementiert Threadpool <job> {// Maximale Anzahl von Threads für Thread Pool -Wartung Arbeiter Thread Private statische statische endgültige int max_worker_numbers = 10; // Standardwert des Thread Pool -Wartungsarbeiter Thread Private statische endgültige int default_worker_numbers = 5; // Mindestanzahl der Thread Pool -Wartung Arbeiter Thread Private statische endgültige int min_worker_numbers = 1; // eine Arbeitsliste unterhalten, die die von Kunden initiierte Arbeit privat Final LinkedList <job> Jobs = New LinkedList <job> () hinzufügt; // Liste der Worker -Threads Private Final List <Works> Workers = Collections.SynchronizedList (New ArrayList <Works> ()); // Anzahl der Arbeiter -Threads privat int Workernum; // private atomiclong threadnum = new Atomiclong () generieren; // Thread Pool public default threadpool () {this.workernum = default_worker_numbers; Arbeitnehmer initialisieren (this.workernum); } public default threadpool (int num) {if (num> max_worker_numbers) {this.workernum = default_worker_numbers; } else {this.workernum = num; } initialisieren Arbeitern (this.workernum); } // Initialisieren Sie jeden Worker -Thread private void initialisieren (int num) {für (int i = 0; i <num; i ++) {Worker Worker = new Worker (); // In die Liste der Arbeiter -Threads Workers.add (Arbeiter) hinzufügen; // Starten Sie den Worker -Thread -Thread = neuer Thread (Arbeiter); Thread.Start (); }} public void execute (job Job) {if (Job! = null) {// Gemäß dem "Warte/Benachrichtigung von Threads" müssen wir Jobs synchronisiert (Jobs) {Jobs.addlast (Job); Jobs.notify (); }}} // Schließen Sie den Thread -Pool, der jeden Worker -Thread öffentlich void schaltdown () {für (Arbeiter W: Arbeiter) {W.Shutdown (); }}} // Worker -Thread public void Addworker hinzufügen (int num) {// Sperre hinzufügen, um zu verhindern, dass der Thread zunimmt oder abgeschlossen wird, während der nächste Thread weiter zunimmt, wodurch der Arbeiter -Thread den maximalen Wert synchronisiert (Jobs) {if (num + this.workernum> max_worker_numbers) {num = mAx_worker_worker_numbers - thaNumern; } initialisieren Arbeitskräften (num); this.workernum += num; }} // Arbeiter -Thread public void entfernen (int num) {synchronisierte (Jobs) {if (num> = this.workernum) {Neue IllegalArgumentException ("Überschreiten Sie die Anzahl der vorhandenen Threads überschreiten"); } für (int i = 0; i <num; i ++) {Worker Worker = Workers.get (i); if (Worker! Arbeiter.Remove (i); }} this.workernum -= num; }} public int getJobsize () {// Todo automatisch generierte Methode Stub return Workers.size (); } // Definieren Sie die Worker -Thread -Klasse -Arbeiter implementiert Runnable {// Gibt an, ob der private volatile boolean running = true; public void run () {while (laufen) {Job Job = null; // Thread Wait/Benachrichtigungsmechanismus synchronisiert (Jobs) {if (Jobs.isempty ()) {try {Jobs.wait (); // Thread wartet auf Weck -} catch (InterruptedException e) {// erdenkt die externe Interrupt -Operation auf dem Thread und gibt Thread zurück. zurückkehren; }} // Nehmen Sie einen Job auf Job = Jobs.removeFirst (); } // Job if (Job! = Null) {Job.run (); }}} // den Thread public void stilldown () {running = false; }}}
Aus der Implementierung des Thread -Pools ist ersichtlich, dass der Kunde, wenn der Kunde die Ausführungsmethode aufruft, ständig Jobs zu den Aufgabenlistenaufträgen hinzufügt und jeder Arbeiter -Thread die Jobs nicht aus den Jobs zur Ausführung liest. Wenn die Jobs leer sind, tritt der Arbeiter -Thread in den Wartezustand ein.
Nach dem Hinzufügen eines Jobs wird die Benachrichtigung () -Methode auf die Arbeitskräfte aufgerufen, um einen Arbeiter -Thread aufzuwecken. Hier rufen wir Notifyall () nicht an, um zu vermeiden, dass Ressourcen verschwendet werden, indem alle Themen in der wartenden Warteschlange in die blockierende Warteschlange verschoben werden.
Die Essenz eines Thread-Pools besteht darin, eine Thread-Safe-Arbeitswarteschlange zu verwenden, um Worker-Threads und Client-Threads zu verbinden. Der Client -Thread kehrt zurück, nachdem die Aufgabe in die Arbeitswarteschlange gesteckt wurde, während der Arbeiter -Thread die Arbeit misshandelt hat und sie aus der Arbeitswarteschlange ausführt und sie ausführt. Wenn die Arbeitswarteschlange leer ist, tritt der Arbeiter -Thread in den Wartezustand ein. Wenn ein Kunde eine Aufgabe sendet, wird er einen beliebigen Arbeiter -Thread durchlaufen. Mit der Einreichung einer großen Anzahl von Aufgaben werden mehr Arbeiterfäden geweckt.
Referenz: "Die Kunst der gleichzeitigen Programmierung in Java" Fang Tengfei