Maison >Java >javaDidacticiel >Comment Java utilise-t-il le pool de threads ? Implémentation des codes.

Comment Java utilise-t-il le pool de threads ? Implémentation des codes.

WBOY
WBOYavant
2023-05-08 14:31:071933parcourir

Principe de base du pool de threads Java

Tous ceux qui ont lu le code source du pool de threads Java savent que la classe principale du pool de threads Java est ThreadPoolExecutor et que la méthode de construction de base dans la classe ThreadPoolExecutor est le constructeur avec la méthode à 7 paramètres, comme indiqué. ci-dessous.

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

La signification de chaque paramètre est la suivante.

  • corePoolSize : Le nombre de threads principaux résidents dans le pool de threads.

  • maximumPoolSize : Le pool de threads peut accueillir le nombre maximum de threads s'exécutant simultanément. Cette valeur est supérieure ou égale à 1.

  • keepAliveTime : Le temps de survie des threads inactifs en excès Lorsque l'espace-temps atteint la valeur keepAliveTime, les threads en excès seront détruits jusqu'à ce qu'il ne reste plus que les threads corePoolSize.

  • unit : unité de keepAliveTime.

  • workQueue : file d'attente des tâches, tâches qui ont été soumises mais qui n'ont pas encore été exécutées.

  • threadFactory : représente la fabrique de threads qui génère des threads de travail dans le pool de threads lorsque les utilisateurs créent de nouveaux threads, la valeur par défaut est généralement suffisante.

  • handler : Stratégie de rejet, indiquant comment rejeter la stratégie d'exécution de requête exécutable lorsque la file d'attente des threads est pleine et que les threads de travail sont supérieurs ou égaux au nombre d'affichage maximum du pool de threads (maxnumPoolSize).

Et le pool de threads de Java est implémenté via le modèle producteur-consommateur L'utilisateur du pool de threads est le producteur, et le pool de threads lui-même est le consommateur.

Le flux de travail principal du pool de threads Java est illustré dans la figure ci-dessous.

Comment Java utilise-t-il le pool de threads ? Implémentation des codes.

Pool de threads Java

Le pool de threads que nous avons implémenté manuellement est beaucoup plus simple que le propre pool de threads de Java. Nous avons supprimé diverses méthodes de traitement complexes et n'avons conservé que le principe de base : pool de threads Un consommateur ajoute des tâches à la tâche. file d'attente, tandis que le pool de threads lui-même consomme les tâches de la file d'attente des tâches et exécute les tâches.

Comment Java utilise-t-il le pool de threads ? Implémentation des codes.

Tant que vous comprenez ce principe de base, le prochain code sera beaucoup plus simple. Lors de l’implémentation de ce simple pool de threads, nous pouvons démonter l’ensemble du processus d’implémentation. Le processus d'implémentation démantelé est le suivant : définir les champs principaux, créer la classe interne WorkThread, créer le constructeur de la classe ThreadPool et créer la méthode pour exécuter la tâche.

Définir les champs principaux

Tout d'abord, nous créons une classe Java nommée ThreadPool et définissons les champs principaux suivants dans cette classe.

  • DEFAULT_WORKQUEUE_SIZE : Constante statique, indiquant la taille de la file d'attente de blocage par défaut.

  • workQueue : simule un pool de threads réel en utilisant une file d'attente de blocage pour implémenter le modèle producteur-consommateur.

  • workThreads : simulez le pool de threads réel et utilisez la collection List pour enregistrer les threads de travail dans le pool de threads.

Le code de base est le suivant.

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

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

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

Créez la classe interne WordThread

Créez une classe interne WorkThread dans la classe ThreadPool pour simuler le thread de travail dans le pool de threads. La fonction principale est de consommer des tâches dans workQueue et d'exécuter les tâches. Étant donné que le thread de travail doit obtenir en permanence des tâches de workQueue, une boucle while (true) est utilisée ici pour essayer en permanence de consommer les tâches dans la file d'attente.

Le code de base est le suivant.

//内部类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();
            }
        }
    }
}

Créez le constructeur de la classe ThreadPool

Ici, nous créons deux constructeurs pour la classe ThreadPool. Dans un constructeur, la capacité du pool de threads et de la file d'attente de blocage sont transmises, et dans l'autre constructeur, seule la capacité. du pool de threads est transmis.

Le code de base est le suivant.

//在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));
}

Créer une méthode d'exécution de tâches

Créer une méthode d'exécution de tâches, exécuté(), dans la classe ThreadPool L'implémentation de la méthode exécuter() est relativement simple, qui consiste à ajouter les tâches Runnable reçues par la méthode. à la file d'attente workQueue.

Le code de base est le suivant.

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

Code source complet

Ici, nous donnons le code source complet du pool de threads ThreadPool implémenté manuellement, comme indiqué ci-dessous.

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();
                }
            }
        }
    }
}

Oui, nous n'avons utilisé que des dizaines de lignes de code Java pour implémenter une version minimaliste du pool de threads Java Oui, le code de cette version minimaliste du pool de threads Java incarne les principes fondamentaux du pool de threads Java.

Ensuite, testons cette version minimaliste du pool de threads Java.

Ecrire un programme de test

Le programme de test est également relativement simple. Il s'agit d'appeler le constructeur de la classe ThreadPool dans la méthode main(), de passer la taille du pool de threads, de créer une instance de la classe ThreadPool, puis bouclez 10 fois pour appeler la méthode exécuter() de la classe ThreadPool, la tâche soumise au pool de threads est : 打印当前线程的名称--->> Hello ThreadPool.

Le code global du test est le suivant.

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");
            });
        });
    }
}

Ensuite, exécutez la méthode main() de la classe ThreadPoolTest et les informations suivantes seront affichées.

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

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer