Pool de threads JAVA manuscrits

avant-propos

Écrire à la main un simple pool de threads Java : comment s'assurer qu'il y a toujours des threads en cours d'exécution ? Comment s'assurer que le thread consomme les informations de tâche soumises ? . Le thread sous-jacent qui a été maintenu en cours d'exécution est une boucle infinie. Utilisez des files d'attente de messages pour assurer la soumission et la consommation d'informations. Les files d'attente de messages utilisent le principe du premier entré, premier sorti.

marcher

Le point central du pool de threads : mécanisme de multiplexage

  • 1. Créez un thread fixe à l'avance et continuez à fonctionner ---- implémentation de la boucle infinie
  • 2. Les tâches de thread soumises sont mises en cache dans un ensemble de files d'attente simultanées et transmises à nos threads en cours d'exécution pour exécution
  • 3. Le thread en cours d'exécution obtient l'exécution de la tâche à partir de la file d'attente

1. Créer un fil fixe

En fonction des paramètres transmis, déterminez le nombre de threads à exécuter en permanence. Par exemple, si le paramètre passé est 2, deux threads toujours en cours d'exécution seront créés. Les threads toujours en cours d'exécution sont implémentés à l'aide d'une boucle infinie.

public class MyTestExecutors {
    private List<WorkThread> workThread;

    /**
     * 最大线程数
     * @param maxThreadCount
     */
    public MyTestExecutors(int maxThreadCount){
        //提前创建好固定的线程一直在运行状态---死循环实现
        workThread = new ArrayList<WorkThread>(maxThreadCount);
        for (int i = 0; i < maxThreadCount; i++) {
            new WorkThread().start();
        }
    }

    class WorkThread extends Thread{
        @Override
        public void run() {
            while (true){

            }
        }
    }
}

2. Soumettre la tâche à la file d'attente des messages

Les tâches de thread soumises sont mises en cache dans une collection de files d'attente simultanées et transmises à nos threads en cours d'exécution pour exécution.

Astuce : La méthode offre() est une méthode souvent utilisée dans les files d'attente Java, et sa fonction est d'ajouter un élément à la fin de la file d'attente. Plus précisément, la méthode offer() insérera l'élément spécifié à la fin de cette file d'attente et renverra false si la file d'attente est pleine . Sinon, elle renvoie true, indiquant que l'élément a été ajouté avec succès.

    /**
     * 线程任务缓存到一个并发队列集合
     * @param command
     * @return
     */
    public boolean execute(Runnable command){
    
    
        return runnableDeque.offer(command);
    }

public class MyTestExecutors {
    
    
    private List<WorkThread> workThread; //工作线程
    private BlockingDeque<Runnable> runnableDeque; //队列


    /**
     * @param maxThreadCount 最大线程数
     * @param dequeSize      缓存消息队列
     */
    public MyTestExecutors(int maxThreadCount,int dequeSize){
    
    
        //1、限制队列容量缓存
        runnableDeque = new LinkedBlockingDeque<Runnable>(dequeSize);
        //2、提前创建好固定的线程一直在运行状态---死循环实现
        workThread = new ArrayList<WorkThread>(maxThreadCount);
        for (int i = 0; i < maxThreadCount; i++) {
    
    
            new WorkThread().start();
        }

    }

    class WorkThread extends Thread{
    
    
        @Override
        public void run() {
    
    
            while (true){
    
    

            }
        }
    }

    /**
     * 线程任务缓存到一个并发队列集合
     * @param command
     * @return
     */
    public boolean execute(Runnable command){
    
    
        return runnableDeque.offer(command);
    }

    public static void main(String[] args) {
    
    
        MyTestExecutors testExecutors = new MyTestExecutors(2, 2);
        for (int i = 0; i < 10; i++) {
    
    
            final int finalI = i;
            testExecutors.execute(new Runnable() {
    
    
                @Override
                public void run() {
    
    
                    System.out.println(Thread.currentThread().getName()+","+finalI);
                }
            });
        }
    }
}

3. File d'attente de messages de consommation de threads

Le thread en cours d'exécution obtient l'exécution de la tâche à partir de la file d'attente

    class WorkThread extends Thread{
    
    
        @Override
        public void run() {
    
    
            while (true){
    
    
                Runnable runnable = runnableDeque.poll();
                if(runnable != null){
    
    
                    runnable.run();
                }
            }
        }
    }

4. Testez

Dans le cas de 2, les deux threads fixes n'ont pas encore exécuté de tâches, et seules deux tâches de thread sont mises en cache dans la file d'attente.

insérez la description de l'image ici

Dans le cas de 4, il est résolu que deux threads exécutent des tâches et que deux tâches de thread sont mises en cache dans la file d'attente.
insérez la description de l'image ici

5. Arrêt du fil [code complet]

Comment arrêter deux threads existants une fois l'exécution de la tâche de thread terminée. Il est nécessaire de changer la condition de la boucle infinie en donnant un bit drapeau. Une fois la tâche terminée, définissez le bit d'indicateur sur faux et, en même temps, il doit juger si l'exécution des tâches dans la file d'attente est terminée. Le thread n'est arrêté qu'une fois toutes les tâches mises en cache dans la file d'attente terminées.

tandis que (isRun || runnableDeque.size()>0)

package com.grg.demo.testDemo02;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;

/**
 * @author zyz
 * @version 1.0
 * @data 2023/7/11 23:01
 * @Description: 手写线程池
 *  线程池核心点 :复用机制 -----
 *  1、提前创建好固定的线程一直在运行状态----死循环实现
 *  2、提交的线程任务缓存到一个并发队列集合中,交给我们正在运行的线程执行
 *  3、正在运行的线程就从队列中获取该任务执行
 */
public class MyTestExecutors {
    
    
    private List<WorkThread> workThread; //工作线程
    private BlockingDeque<Runnable> runnableDeque; //队列
    private Boolean isRun = true;

    /**
     *
     * @param maxThreadCount 最大线程数
     * @param dequeSize      缓存消息队列
     */
    public MyTestExecutors(int maxThreadCount,int dequeSize){
    
    
        //2、限制队列容量缓存
        runnableDeque = new LinkedBlockingDeque<Runnable>(dequeSize);
        //1、提前创建好固定的线程一直在运行状态---死循环实现
        workThread = new ArrayList<WorkThread>(maxThreadCount);
        for (int i = 0; i < maxThreadCount; i++) {
    
    
            new WorkThread().start();
        }

    }

    class WorkThread extends Thread{
    
    
        @Override
        public void run() {
    
    
            while (isRun || runnableDeque.size()>0){
    
    
                Runnable runnable = runnableDeque.poll();
                if(runnable != null){
    
    
                    runnable.run();
                }
            }
        }
    }

    /**
     * 线程任务缓存到一个并发队列集合
     * @param command
     * @return
     */
    public boolean execute(Runnable command){
    
    
        return runnableDeque.offer(command);
    }

    public static void main(String[] args) {
    
    
        MyTestExecutors testExecutors = new MyTestExecutors(2, 2);
        for (int i = 0; i < 10; i++) {
    
    
            final int finalI = i+1;
            testExecutors.execute(new Runnable() {
    
    
                @Override
                public void run() {
    
    
                    System.out.println(Thread.currentThread().getName()+","+finalI);
                }
            });
        }
        testExecutors.isRun = false;
    }
}

insérez la description de l'image ici

Je suppose que tu aimes

Origine blog.csdn.net/weixin_43304253/article/details/131671117
conseillé
Classement