Inhaltsverzeichnis
Die Vorteile des Thread-Pools
Fünf Möglichkeiten, einen Thread-Pool zu erstellen
CachedThreadPool
Thread-Pool mit fester Kapazität FixedThreadPool
Single-Thread-Pool SingleThreadExecutor
ScheduledThreadPool
ThreadPoolExecutor erstellt einen Thread-Pool (sehr zu empfehlen)
Detaillierte Erklärung der sieben Parameter von ThreadPoolExecutor
workQueue
handler
如何触发拒绝策略和线程池扩容?
Heim Java javaLernprogramm So erstellen Sie einen Java-Thread-Pool

So erstellen Sie einen Java-Thread-Pool

May 16, 2023 am 08:43 AM
java

Die Vorteile des Thread-Pools

  • können die Wiederverwendung von Threads realisieren und das erneute Erstellen und Zerstören von Threads vermeiden. Das Erstellen und Zerstören von Threads ist für die CPU sehr kostspielig.

  • Sie können die maximale Anzahl der Threads begrenzen, die erstellt werden können, und die Thread-Pool-Parameter dynamisch an die Leistung Ihres eigenen Computers anpassen, um die Anwendungsleistung zu verbessern.

  • Bietet Funktionen wie geplante Ausführung und Parallelitätskontrolle.

  • Einheitliche Verwaltung von Threads.

Fünf Möglichkeiten, einen Thread-Pool zu erstellen

1: Cache-Thread-Pool (nicht empfohlen)

2: Thread-Pool mit fester Kapazität (nicht empfohlen)

3: Einzelner Thread-Pool (nicht empfohlen)

4: Timing Aufgaben-Thread-Pool (nicht empfohlen)

5: Erstellen Sie einen Thread-Pool über die ThreadPoolExecutor-Konstruktionsmethode (im Alibaba-Entwicklungshandbuch dringend empfohlen)

Die ersten vier Möglichkeiten zum Erstellen eines Thread-Pools werden alle über die statischen Methoden von Executors erstellt.

CachedThreadPool

	ExecutorService executorService = Executors.newCachedThreadPool();

        for (int i = 0; i < 10; i++) {
            final int finalI = i;
            executorService.execute(new Runnable() {
                public void run() {
                    System.out.println(Thread.currentThread().getName()+"<thread->run>"+ finalI);
                }
            });
        }
Nach dem Login kopieren

Warum wird der zwischengespeicherte Thread-Pool nicht empfohlen?

Quellcode-Analyse

public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, 2147483647, 60L, TimeUnit.SECONDS, new SynchronousQueue());
    }
Nach dem Login kopieren
 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler);
    }
Nach dem Login kopieren

Anhand der beiden oben genannten Codeausschnitte können wir sehen, dass die maximale PoolSize von CachedThreadPool der Maximalwert von Integer 2147483647 ist, was einer unbegrenzten Thread-Erstellung entspricht, und das Erstellen von Threads erfordert Speicher, was zu einem Speicherüberlauf führt , und normale Maschinen benötigen keinen so großen Speicher, um eine so große Anzahl von Threads zu erstellen.

Thread-Pool mit fester Kapazität FixedThreadPool

newFixedThreadPool(int num), num ist die feste Anzahl von Threads, die wir angeben möchten

	ExecutorService executorService = Executors.newFixedThreadPool(5);

      for (int i = 0; i < 10; i++) {
          final int finalI = i;
          executorService.execute(new Runnable() {
              public void run() {
                  System.out.println(Thread.currentThread().getName()+"<thread->run>"+ finalI);
              }
          });
      }
Nach dem Login kopieren

Ausgabe:

pool-1-thread-5run>4
pool- 1-thread-4run>3
pool-1-thread-5run>5
pool-1-thread-3run>2
pool- 1- thread-3run>8
pool-1-thread-3run>9
pool-1-thread-2run>1
pool-1- thread- 1run>0
pool-1-thread-5run>7
pool-1-thread-4run>6

Es ist zu sehen dass Threads zur Wiederverwendung verwendet werden.

Warum ist FixedThreadPool ein fester Thread-Pool?

Quellcode-Analyse

public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue());
    }
Nach dem Login kopieren

Aus diesem Quellcode ist ersichtlich, dass die Anzahl der Kern-Threads (corePoolSize) und die maximale Anzahl von Threads (maximumPoolSize) beide nThreads sind, da der Thread-Pool nur auf diese Weise nicht vorhanden ist erweitert und die Anzahl der Threads wird festgelegt.

Single-Thread-Pool SingleThreadExecutor

	ExecutorService executorService = Executors.newSingleThreadExecutor();

      for (int i = 0; i < 10; i++) {
          final int finalI = i;
          executorService.execute(new Runnable() {
              public void run() {
                  System.out.println(Thread.currentThread().getName()+"<thread->run>"+ finalI);
              }
          });

      }
Nach dem Login kopieren

Warum enthält SingleThreadExecutor nur einen Thread?

Quellcode-Analyse

public static ExecutorService newSingleThreadExecutor() {
        return new Executors.FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()));
    }
Nach dem Login kopieren

Aus diesem Quellcode ist ersichtlich, dass die Anzahl der Kernthreads (corePoolSize) und die maximale Anzahl von Threads (maximumPoolSize) jeweils 1 sind, sodass nur ein Thread enthalten ist.

ScheduledThreadPool

	  int initDelay=10; //初始化延时
      int period=1;//初始化延迟过了之后,每秒的延时

      ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(10);

      scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
          @Override
          public void run() {
              System.out.println(Thread.currentThread().getName()+"<thread->run>");
          }
      },initDelay,period, TimeUnit.SECONDS);
Nach dem Login kopieren

Die Wirkung dieses Codes ist: Warten Sie 10 Sekunden, nachdem das Programm ausgeführt wurde, geben Sie dann das erste Ergebnis aus und geben Sie das Ergebnis dann alle 1 Sekunde aus.

Warum wird ScheduledThreadPool nicht empfohlen?

Quellcode-Analyse

public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, 2147483647, 10L, TimeUnit.MILLISECONDS, new ScheduledThreadPoolExecutor.DelayedWorkQueue());
    }
Nach dem Login kopieren

Es ist ersichtlich, dass die maximale Anzahl von Threads (maximumPoolSize) von ScheduledThreadPool dem Maximalwert von Integer 2147483647 entspricht, was einer unbegrenzten Thread-Erstellung entspricht, und das Erstellen von Threads erfordert Speicher, was zu einem Speicherüberlauf führt , und im Allgemeinen Die Maschine verwendet keinen so großen Speicher, um eine so große Anzahl von Threads zu erstellen.

ThreadPoolExecutor erstellt einen Thread-Pool (sehr zu empfehlen)

	ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 20,
              2L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(5),
              Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());

      for (int i = 0; i < 12; i++) {
          final int finalI = i;
          threadPoolExecutor.execute(new Runnable() {
              public void run() {
                  System.out.println(Thread.currentThread().getName()+"<thread->run>"+ finalI);
              }
          });
      }
Nach dem Login kopieren
Detaillierte Erklärung der sieben Parameter von ThreadPoolExecutor
	public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
        
    }
Nach dem Login kopieren
  • corePoolSize: die Anzahl der Kern-Threads. Sobald diese Threads erstellt wurden, werden sie nicht zerstört und bleiben immer bestehen. Der Thread-Pool verfügt standardmäßig über keine Threads. Wenn eine Aufgabe eintrifft, wird über ThreadFactory ein Thread erstellt, der immer vorhanden ist.

  • maximumPoolSize: Maximale Anzahl von Threads. Die Anzahl der Nicht-Kern-Threads = MaximumPoolSize-CorePoolSize. Die Anzahl der Nicht-Kern-Threads entspricht tatsächlich der Anzahl der skalierbaren Threads und kann zerstört werden.

  • keepAliveTime: Die Leerlaufzeit von Nicht-Kern-Threads. Wenn die Anzahl der durch die Erweiterung generierten Nicht-Kern-Threads nach der keepAliveTime immer noch im Leerlauf ist, werden diese Nicht-Kern-Threads zerstört.

  • Einheit: Zeiteinheit von keepAliveTime, zum Beispiel: Sekunden

  • workQueue: Wartebereich. Wenn eine Aufgabe > corePoolSize eintrifft, wird die Aufgabe in der blockierenden Warteschlange von workQueue gespeichert und wartet darauf, dass andere Threads sie verarbeiten.

  • threadFactory: Thread-Fabrik. Eine Möglichkeit, Threads zu erstellen.

  • Handler: Ablehnungsstrategie. Wenn es um > die maximale Anzahl von Threads + die Kapazität von workQueue geht, wird die Ablehnungsrichtlinie ausgeführt

workQueue

ArrayBlockingQueue: begrenzte Blockierungswarteschlange. Die Warteschlange hat eine Größenbeschränkung. Wenn die Kapazität überschritten wird, wird die Erweiterungs- oder Ablehnungsrichtlinie ausgelöst.

	public ArrayBlockingQueue(int capacity) {
        this(capacity, false);
    }
Nach dem Login kopieren

LinkedBlockingQueue: Unbegrenzte Blockierungswarteschlange, die Warteschlange hat keine Größenbeschränkung und kann zu einem Speicherüberlauf führen.

	 public LinkedBlockingQueue() {
        this(2147483647);
    }
Nach dem Login kopieren
handler

AbortPolicy: Eine Ausnahme direkt auslösen

	public static class AbortPolicy implements RejectedExecutionHandler {
        public AbortPolicy() {
        }

        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            throw new RejectedExecutionException("Task " + r.toString() + " rejected from " + e.toString());
        }
    }
Nach dem Login kopieren

DiscardPolicy: Es wird keine Operation ausgeführt. Verwerfen Sie die Aufgabe stillschweigend.

	public static class DiscardPolicy implements RejectedExecutionHandler {
        public DiscardPolicy() {
        }

        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        }
    }
Nach dem Login kopieren

DiscardOldestPolicy: Verwerfen Sie die am längsten vorhandene Aufgabe

	ThreadFactory threadFactory = Executors.defaultThreadFactory();

      threadFactory.newThread(new Runnable() {
          @Override
          public void run() {
              System.out.println("threadFactory");
          }
      }).start();
Nach dem Login kopieren
如何触发拒绝策略和线程池扩容?
	ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 20,
              2L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(5),
              Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());

      for (int i = 0; i < 26; i++) { //并发数26
          final int finalI = i;
          threadPoolExecutor.execute(new Runnable() {
              public void run() {
                  System.out.println(Thread.currentThread().getName()+"<thread->run>"+ finalI);
              }
          });
      }
      /**
       * 核心线程数=10,最大线程数=20,故可扩容线程数=20-10
       * BlockingQueue的大小为5,故等待区的大小为5,也就是当并发数<=核心线程数+5不会扩容,并发数大于16才会扩容
       *
       * 触发扩容:并发数>核心线程数+阻塞队列的大小
       * 对于这段代码,如果来了26个并发,10个并发会被核心线程处理,5个会在等待区,剩下11个会因为等待区满了而触发扩容
       * 因为这里最多能够扩容10个,这里却是11个,所以会触发拒绝策略
       */
Nach dem Login kopieren
  • 为什么这段代码会触发拒绝策略

对于这段代码,如果来了26个并发,10个并发会被核心线程处理,5个会在等待区,剩下11个会因为等待区满了而触发扩容,但是又因为因为这里最多能够扩容10个,这里却是11个,所以会触发拒绝策略。

  • 怎么触发扩容

触发扩容:并发数>核心线程数(corePoolSize)+阻塞队列(workQueue)的大小

  • 使用Java纯手写一个线程池

Das obige ist der detaillierte Inhalt vonSo erstellen Sie einen Java-Thread-Pool. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Quadratwurzel in Java Quadratwurzel in Java Aug 30, 2024 pm 04:26 PM

Leitfaden zur Quadratwurzel in Java. Hier diskutieren wir anhand eines Beispiels und seiner Code-Implementierung, wie Quadratwurzel in Java funktioniert.

Perfekte Zahl in Java Perfekte Zahl in Java Aug 30, 2024 pm 04:28 PM

Leitfaden zur perfekten Zahl in Java. Hier besprechen wir die Definition, Wie prüft man die perfekte Zahl in Java?, Beispiele mit Code-Implementierung.

Zufallszahlengenerator in Java Zufallszahlengenerator in Java Aug 30, 2024 pm 04:27 PM

Leitfaden zum Zufallszahlengenerator in Java. Hier besprechen wir Funktionen in Java anhand von Beispielen und zwei verschiedene Generatoren anhand ihrer Beispiele.

Armstrong-Zahl in Java Armstrong-Zahl in Java Aug 30, 2024 pm 04:26 PM

Leitfaden zur Armstrong-Zahl in Java. Hier besprechen wir eine Einführung in die Armstrong-Zahl in Java zusammen mit einem Teil des Codes.

Weka in Java Weka in Java Aug 30, 2024 pm 04:28 PM

Leitfaden für Weka in Java. Hier besprechen wir die Einführung, die Verwendung von Weka Java, die Art der Plattform und die Vorteile anhand von Beispielen.

Smith-Nummer in Java Smith-Nummer in Java Aug 30, 2024 pm 04:28 PM

Leitfaden zur Smith-Zahl in Java. Hier besprechen wir die Definition: Wie überprüft man die Smith-Nummer in Java? Beispiel mit Code-Implementierung.

Fragen zum Java Spring-Interview Fragen zum Java Spring-Interview Aug 30, 2024 pm 04:29 PM

In diesem Artikel haben wir die am häufigsten gestellten Fragen zu Java Spring-Interviews mit ihren detaillierten Antworten zusammengestellt. Damit Sie das Interview knacken können.

Brechen oder aus Java 8 Stream foreach zurückkehren? Brechen oder aus Java 8 Stream foreach zurückkehren? Feb 07, 2025 pm 12:09 PM

Java 8 führt die Stream -API ein und bietet eine leistungsstarke und ausdrucksstarke Möglichkeit, Datensammlungen zu verarbeiten. Eine häufige Frage bei der Verwendung von Stream lautet jedoch: Wie kann man von einem Foreach -Betrieb brechen oder zurückkehren? Herkömmliche Schleifen ermöglichen eine frühzeitige Unterbrechung oder Rückkehr, aber die Stream's foreach -Methode unterstützt diese Methode nicht direkt. In diesem Artikel werden die Gründe erläutert und alternative Methoden zur Implementierung vorzeitiger Beendigung in Strahlverarbeitungssystemen erforscht. Weitere Lektüre: Java Stream API -Verbesserungen Stream foreach verstehen Die Foreach -Methode ist ein Terminalbetrieb, der einen Vorgang für jedes Element im Stream ausführt. Seine Designabsicht ist

See all articles