Heim  >  Artikel  >  Java  >  Wie nutzt Java den Thread-Pool? Code-Implementierung.

Wie nutzt Java den Thread-Pool? Code-Implementierung.

WBOY
WBOYnach vorne
2023-05-08 14:31:071876Durchsuche

Kernprinzip des Java-Thread-Pools

Jeder, der den Java-Thread-Pool-Quellcode gelesen hat, weiß, dass die Kernklasse im Java-Thread-Pool ThreadPoolExecutor ist und die Kernkonstruktionsmethode in der ThreadPoolExecutor-Klasse die Konstruktormethode as ist unten dargestellt.

 public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)

Die Bedeutung jedes Parameters ist wie folgt.

  • corePoolSize: Die Anzahl der residenten Kernthreads im Thread-Pool.

  • maximumPoolSize: Der Thread-Pool kann die maximale Anzahl gleichzeitig ausgeführter Threads aufnehmen. Dieser Wert ist größer oder gleich 1.

  • keepAliveTime: Die Überlebenszeit überschüssiger Leerlauf-Threads. Wenn die Raumzeit den keepAliveTime-Wert erreicht, werden die überschüssigen Threads zerstört, bis nur noch corePoolSize-Threads übrig sind.

  • Einheit: Einheit von keepAliveTime.

  • workQueue: Aufgabenwarteschlange, Aufgaben, die übermittelt, aber noch nicht ausgeführt wurden.

  • threadFactory: Stellt die Thread-Factory dar, die Arbeitsthreads im Thread-Pool generiert. Wenn Benutzer neue Threads erstellen, ist die Standardeinstellung im Allgemeinen ausreichend.

  • Handler: Ablehnungsstrategie, die angibt, wie die Ausführungsstrategie für ausführbare Anforderungen abgelehnt werden soll, wenn die Thread-Warteschlange voll ist und die Arbeitsthreads größer oder gleich der maximal angezeigten Anzahl des Thread-Pools (maxnumPoolSize) sind.

Und der Thread-Pool von Java wird durch das Produzenten-Konsumenten-Modell implementiert. Der Benutzer des Thread-Pools ist der Produzent und der Thread-Pool selbst ist der Verbraucher.

Der Kernworkflow des Java-Thread-Pools ist in der folgenden Abbildung dargestellt.

Wie nutzt Java den Thread-Pool? Code-Implementierung.

Hands on Java Thread Pool

Der von uns manuell implementierte Thread Pool ist viel einfacher als Javas eigener Thread Pool. Wir haben verschiedene komplexe Verarbeitungsmethoden entfernt und nur das Kernprinzip beibehalten: Thread Pool Ein Verbraucher fügt der Aufgabe Aufgaben hinzu Warteschlange, während der Thread-Pool selbst Aufgaben aus der Aufgabenwarteschlange verbraucht und Aufgaben ausführt.

Wie nutzt Java den Thread-Pool? Code-Implementierung.

Solange Sie dieses Grundprinzip verstehen, wird der nächste Code viel einfacher sein. Bei der Implementierung dieses einfachen Thread-Pools können wir den gesamten Implementierungsprozess zerlegen. Der zerlegte Implementierungsprozess besteht aus: Definieren von Kernfeldern, Erstellen der internen Klasse WorkThread, Erstellen des Konstruktors der ThreadPool-Klasse und Erstellen der Methode zum Ausführen der Aufgabe.

Kernfelder definieren

Zuerst erstellen wir eine Java-Klasse namens ThreadPool und definieren die folgenden Kernfelder in dieser Klasse.

  • DEFAULT_WORKQUEUE_SIZE: Statische Konstante, die die Standardgröße der Blockierungswarteschlange angibt.

  • workQueue: simuliert einen tatsächlichen Thread-Pool mithilfe einer Blockierungswarteschlange, um das Producer-Consumer-Muster zu implementieren.

  • workThreads: Simulieren Sie den tatsächlichen Thread-Pool und verwenden Sie die List-Sammlung, um die Arbeitsthreads im Thread-Pool zu speichern.

Der Kerncode lautet wie folgt.

//默认阻塞队列大小
private static final int DEFAULT_WORKQUEUE_SIZE = 5;

//模拟实际的线程池使用阻塞队列来实现生产者-消费者模式
private BlockingQueue<Runnable> workQueue;

//模拟实际的线程池使用List集合保存线程池内部的工作线程
private List<WorkThread> workThreads = new ArrayList<WorkThread>();

Erstellen Sie die interne Klasse WordThread.

Erstellen Sie eine interne Klasse WorkThread in der ThreadPool-Klasse, um den Arbeitsthread im Thread-Pool zu simulieren. Die Hauptfunktion besteht darin, Aufgaben in der WorkQueue zu konsumieren und auszuführen. Da der Arbeitsthread kontinuierlich Aufgaben aus der WorkQueue abrufen muss, wird hier eine while-Schleife (true) verwendet, um kontinuierlich zu versuchen, Aufgaben in der Warteschlange zu verbrauchen.

Der Kerncode lautet wie folgt.

//内部类WorkThread,模拟线程池中的工作线程
//主要的作用就是消费workQueue中的任务,并执行
//由于工作线程需要不断从workQueue中获取任务,使用了while(true)循环不断尝试消费队列中的任务
class WorkThread extends Thread{
    @Override
    public void run() {
        //不断循环获取队列中的任务
        while (true){
            //当没有任务时,会阻塞
            try {
                Runnable workTask = workQueue.take();
                workTask.run();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

Erstellen Sie den Konstruktor der ThreadPool-Klasse

Hier erstellen wir zwei Konstruktoren für die ThreadPool-Klasse. In einem Konstruktor werden die Kapazität des Thread-Pools und der Blockierungswarteschlange übergeben, im anderen Konstruktor nur die Kapazität des Thread-Pools wird übergeben. Größe.

Der Kerncode lautet wie folgt.

//在ThreadPool的构造方法中传入线程池的大小和阻塞队列
public ThreadPool(int poolSize, BlockingQueue<Runnable> workQueue){
    this.workQueue = workQueue;
    //创建poolSize个工作线程并将其加入到workThreads集合中
    IntStream.range(0, poolSize).forEach((i) -> {
        WorkThread workThread = new WorkThread();
        workThread.start();
        workThreads.add(workThread);
    });
}

//在ThreadPool的构造方法中传入线程池的大小
public ThreadPool(int poolSize){
    this(poolSize, new LinkedBlockingQueue<>(DEFAULT_WORKQUEUE_SIZE));
}

Erstellen Sie eine Methode zum Ausführen von Aufgaben.

Erstellen Sie eine Methode „execute()“ in der ThreadPool-Klasse, um eine Aufgabe auszuführen. Die Implementierung der Methode „execute()“ ist relativ einfach, nämlich das Hinzufügen der von der Methode empfangenen ausführbaren Aufgabe die workQueue-Warteschlange.

Der Kerncode lautet wie folgt.

//通过线程池执行任务
public void execute(Runnable task){
    try {
        workQueue.put(task);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

Vollständiger Quellcode

Hier geben wir den vollständigen Quellcode des manuell implementierten ThreadPool-Thread-Pools an, wie unten gezeigt.

package io.binghe.thread.pool;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.stream.IntStream;

/**
 * @author binghe
 * @version 1.0.0
 * @description 自定义线程池
 */
public class ThreadPool {

    //默认阻塞队列大小
    private static final int DEFAULT_WORKQUEUE_SIZE = 5;

    //模拟实际的线程池使用阻塞队列来实现生产者-消费者模式
    private BlockingQueue<Runnable> workQueue;

    //模拟实际的线程池使用List集合保存线程池内部的工作线程
    private List<WorkThread> workThreads = new ArrayList<WorkThread>();

    //在ThreadPool的构造方法中传入线程池的大小和阻塞队列
    public ThreadPool(int poolSize, BlockingQueue<Runnable> workQueue){
        this.workQueue = workQueue;
        //创建poolSize个工作线程并将其加入到workThreads集合中
        IntStream.range(0, poolSize).forEach((i) -> {
            WorkThread workThread = new WorkThread();
            workThread.start();
            workThreads.add(workThread);
        });
    }

    //在ThreadPool的构造方法中传入线程池的大小
    public ThreadPool(int poolSize){
        this(poolSize, new LinkedBlockingQueue<>(DEFAULT_WORKQUEUE_SIZE));
    }

 //通过线程池执行任务
    public void execute(Runnable task){
        try {
            workQueue.put(task);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    //内部类WorkThread,模拟线程池中的工作线程
    //主要的作用就是消费workQueue中的任务,并执行
    //由于工作线程需要不断从workQueue中获取任务,使用了while(true)循环不断尝试消费队列中的任务
    class WorkThread extends Thread{
        @Override
        public void run() {
            //不断循环获取队列中的任务
            while (true){
                //当没有任务时,会阻塞
                try {
                    Runnable workTask = workQueue.take();
                    workTask.run();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

Ja, wir haben nur Dutzende Zeilen Java-Code verwendet, um eine minimalistische Version des Java-Thread-Pools zu implementieren. Ja, der Code dieser minimalistischen Version des Java-Thread-Pools verkörpert die Kernprinzipien des Java-Thread-Pools.

Als nächstes testen wir diese minimalistische Version des Java-Thread-Pools.

Ein Testprogramm schreiben

Das Testprogramm ist auch relativ einfach. Es besteht darin, den Konstruktor der ThreadPool-Klasse in der main()-Methode aufzurufen, die Größe des Thread-Pools zu übergeben und eine Instanz der ThreadPool-Klasse zu erstellen. und dann zehnmal wiederholen, um die Methode „execute()“ der ThreadPool-Klasse aufzurufen. Die an den Thread-Pool übermittelte Aufgabe lautet: 打印当前线程的名称--->> Hello ThreadPool.

Der gesamte Testcode lautet wie folgt.

package io.binghe.thread.pool.test;

import io.binghe.thread.pool.ThreadPool;

import java.util.stream.IntStream;

/**
 * @author binghe
 * @version 1.0.0
 * @description 测试自定义线程池
 */
public class ThreadPoolTest {

    public static void main(String[] args){
        ThreadPool threadPool = new ThreadPool(10);
        IntStream.range(0, 10).forEach((i) -> {
            threadPool.execute(() -> {
                System.out.println(Thread.currentThread().getName() + "--->> Hello ThreadPool");
            });
        });
    }
}

Führen Sie als Nächstes die main()-Methode der ThreadPoolTest-Klasse aus und die folgenden Informationen werden ausgegeben.

Thread-0--->> Hallo ThreadPool
Thread-9--->> Hallo ThreadPool
Thread-5--->> Hallo ThreadPool
Thread-8--->> Hallo ThreadPool
Thread-4--->> Hallo ThreadPool
Thread-1--->> Hallo ThreadPool
Thread-2--->> Hallo ThreadPool
Thread-5--->> Hallo ThreadPool
Thread-9--->> Hallo ThreadPool
Thread-0--->> Hallo ThreadPool

Das obige ist der detaillierte Inhalt vonWie nutzt Java den Thread-Pool? Code-Implementierung.. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen