Maison  >  Article  >  Java  >  Comment implémenter la méthode de construction du pool de threads Java

Comment implémenter la méthode de construction du pool de threads Java

avant
2023-04-19 15:13:07732parcourir

1. Introduction

Afin de réaliser la programmation concurrente, le concept de processus a été introduit. Un processus équivaut à une tâche du système d’exploitation. Plusieurs processus exécutent des tâches en même temps, permettant ainsi une programmation simultanée et permettant une exécution plus rapide.

Mais comme le processus n'est pas assez léger, les ressources consommées par la création et la destruction d'un processus ne peuvent être ignorées. Si le nombre de processus n'est pas important, cette consommation de ressources est acceptable, mais si des processus sont fréquemment créés et détruits. Cela représente beaucoup de dépenses.

Que devons-nous faire ?

Afin de résoudre ce problème, les gens ont introduit un outil plus léger : le fil.

Les threads sont également appelés processus légers. Sa création et sa destruction consomment moins de ressources que les processus. Mais que se passe-t-il s'il y a un grand nombre de tâches et que le multithread ne peut pas résister à des créations et des destructions fréquentes ? À ce moment-là, le pool de threads sort pour résoudre le problème !

2. Qu'est-ce que le pool de threads ?

Le pool de threads est similaire au pool de constantes de chaîne Java.

Utiliser des threads VS ne pas utiliser de threads

  • Lorsque vous utilisez un thread, prenez simplement un thread directement dans le pool.

  • Lorsqu'un fil n'est pas nécessaire, mettez ce fil dans le pool

Tout le monde sait que le processus de recherche d'emploi est probablement comme ça.

  • Soumission du curriculum vitae

  • Test écrit

  • Entretien

  • offre

Après l'entretien, il y aura deux situations.

  • Si vous réussissez, l'entreprise vous appellera pour vous en informer et vous enverra une offre

  • Si vous échouez, et généralement l'entreprise ne vous dira pas que vous avez échoué, mais ne vous informera pas que vous avez échoué échoué du tout. C'est parce que l'entreprise peut vous mettre dans son « réserve de talents ».

Supposons que l'entreprise recherche 50 personnes et que pendant la période de recrutement d'automne, elle envoie des offres à 50 personnes. Mais en réalité, seules 35 personnes sont venues se présenter. À ce moment-là, les 15 personnes restantes repêchent directement 15 personnes dans la réserve de talents et font des offres directement.

Peut-être qu'un certain temps s'est écoulé à ce moment-là et que l'entreprise vous appelle soudainement pour vous informer que vous avez été embauché. Voulez-vous venir ? Cette opération équivaut à utiliser un thread directement depuis le pool.

Il s'agit d'utiliser l'exemple de la recherche d'emploi pour décrire ce que signifie probablement le pool de threads.

3. Que signifient les paramètres de la méthode de construction du pool de threads ThreadPoolExecutor ?

Il est souligné dans le « Manuel de développement Java d'Alibaba » que les ressources de thread doivent être fournies via le pool de threads et que la création de threads ne peut pas être affichée dans l'application. D'une part, la création de threads est plus standardisée. et le nombre de threads ouverts peut être raisonnablement contrôlé ; d'un autre côté, la gestion détaillée des threads est gérée par le pool de threads, ce qui optimise la surcharge des ressources.

La classe "ThreadPoolExecutor" est un ensemble de classes fournies par la bibliothèque standard Java pour utiliser les pools de threads.

ThreadPoolExecutor a quatre méthodes de construction. Chacun contient des paramètres différents et est utilisé dans différents scénarios.
Nous présenterons la méthode de construction avec le plus de paramètres.

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

Comment implémenter la méthode de construction du pool de threads Java

1.corePoolSize Nombre de threads principaux

2.maximumPoolSize Nombre maximum de threads

Vous ne comprenez peut-être pas très bien quel est le nombre de threads principaux et le nombre maximum de threads Voici un exemple d'employé. va travailler.

Le nombre de fils centraux fait référence aux employés formels de l'entreprise, leur permettant de pêcher pendant un certain temps. Si vous êtes découvert, vous ne serez pas renvoyé. (Équivalent aux threads du pool de threads qui ne seront pas détruits même s'ils ne font rien)

Le nombre maximum de threads est le nombre d'employés réguliers + intérimaires dans l'entreprise, mais les intérimaires ici pourront pêcher pendant un certain temps Pour être licencié. (Équivalent à la destruction des threads du pool de threads)

3.keepAliveTime décrit la durée pendant laquelle les travailleurs temporaires peuvent pêcher

4.unit est une unité de temps, qui est l'unité de keepAliveTime.

5.workQueue file d'attente de blocage organise les tâches à exécuter par le pool de threads

6.threadFactory méthode de création de thread, utilisez ce paramètre pour définir la méthode de création de différents threads

7.RejectedExecutionHandler stratégie de rejet du gestionnaire. Lorsque la file d'attente des tâches est pleine et qu'une nouvelle tâche arrive, que devons-nous faire à ce moment-là ?

(1) : La dernière tâche n'est plus nécessaire

(2) : La tâche la plus ancienne n'est plus nécessaire

(3) : Blocage et attente

(4) Ouvrir : Lancer une exception

Échu à l'utilisation de ThreadPoolExecutor Cela semble plus compliqué, avec jusqu'à 7 paramètres. La bibliothèque standard fournit aux programmeurs un ensemble de classes supplémentaires à cet effet. C'est équivalent à une autre couche d'encapsulation de ThreadPoolExecutor. 由于ThreadPoolExecutor使用起来比较复杂,最多有7个参数。标准库为此又为程序员们提供了一组其他的类。相当于对ThreadPoolExecutor又进行了一层封装。

1.newFixedThreadPool:创建出一个固定线程数量的线程池。

 ExecutorService Service1   =  Executors.newFixedThreadPool (20);

2.newCachedThreadPool:创建出一个数量可变的线程池

ExecutorService Service2   = Executors.newCachedThreadPool ();

3.newSingleThreadExecutor:创建只有一个线程的线程池

ExecutorService Service3  = Executors.newSingleThreadExecutor ();

4.newScheduledThreadPool

1.newFixedThreadPool : Créez un pool de threads avec un nombre fixe de threads.

ExecutorService Service4   = Executors.newScheduledThreadPool (20);

2.newCachedThreadPool : Créez un nombre variable de pools de threads

模拟实现一个线程池的核心操作:
.:将任务加到线程池中--submit。
.:使用Worker类描述一个工作线程,Runnable来描述一个任务。
.:创建一个BlockingQueue阻塞队列组织所有任务。
.:每个Worker要做的事情就是不停的从阻塞队列里获取任务并执行。
.:指定线程池中的线程最大数目,如果超过这个数目就不要再继续创建线程了。
3.newSingleThreadExecutor : Créez un pool de threads avec un seul thread
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * Created with IntelliJ IDEA.
 *
 
 * @Description: 模拟实现线程池的使用
 */
public class ThreadDemo0327_2 {
    public static void main (String[] args) throws IOException, InterruptedException {
        ThreadPoll threadPoll=new ThreadPoll ();
        for (int i = 0 ; i <10  ; i++) {
            threadPoll.submit (new Runnable () {
                @Override
                public void run () {
                    System.out.println ("hello");
                }
            });
        }
    }
}

class  Worker extends  Thread{
    public   BlockingQueue<Runnable> queue=null;
    public Worker(BlockingQueue<Runnable> queue){
        this.queue=queue;
    }

    @Override
    public void run () {
        //工作线程的具体逻辑
        //需要从阻塞队列中取任务.
        while (true){
            try {
                Runnable command=queue.take ();
                //通过run来执行具体任务
                command.run ();
            }catch (InterruptedException e){
                e.printStackTrace ();
            }
        }
    }
}

class  ThreadPoll{
    //包含一个阻塞队列,用来组织任务
  public   BlockingQueue<Runnable> queue=new LinkedBlockingQueue<> ();

    //这个list就用来存放当前的工作线程.
    public  List<Thread> works=new ArrayList<> ();

    public  int MAX_WORKER_COUNT=10;

    //通过这个方法,把任务加入到线程池中
    //submit不光可以把任务放到阻塞队列中,也可以负责创建线程
    public  void submit(Runnable command) throws IOException, InterruptedException {
        if(works.size ()<MAX_WORKER_COUNT){
            //如果当前工作线程的数量不足线程数目上线,就创建出新的线程
            //工作线程就专门找一个类完成
            //worker内部要哦能够取到队列的内容,就要把这个队列实例通过worker的构造方法传过去
            Worker worker=new Worker (queue);
            worker.start ();
            works.add (worker);
        }
        queue.put (command);
    }
}

4.newScheduledThreadPool : créez un pool de threads qui peut définir le temps de retard. 🎜rrreee🎜4. Simulez et implémentez un pool de threads🎜rrreee🎜🎜Implémentation du code :🎜🎜

我们创建一个线程池并让它不停的创建进程打印hello

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * Created with IntelliJ IDEA.
 *
 
 * @Description: 模拟实现线程池的使用
 */
public class ThreadDemo0327_2 {
    public static void main (String[] args) throws IOException, InterruptedException {
        ThreadPoll threadPoll=new ThreadPoll ();
        for (int i = 0 ; i <10  ; i++) {
            threadPoll.submit (new Runnable () {
                @Override
                public void run () {
                    System.out.println ("hello");
                }
            });
        }
    }
}

class  Worker extends  Thread{
    public   BlockingQueue<Runnable> queue=null;
    public Worker(BlockingQueue<Runnable> queue){
        this.queue=queue;
    }

    @Override
    public void run () {
        //工作线程的具体逻辑
        //需要从阻塞队列中取任务.
        while (true){
            try {
                Runnable command=queue.take ();
                //通过run来执行具体任务
                command.run ();
            }catch (InterruptedException e){
                e.printStackTrace ();
            }
        }
    }
}

class  ThreadPoll{
    //包含一个阻塞队列,用来组织任务
  public   BlockingQueue<Runnable> queue=new LinkedBlockingQueue<> ();

    //这个list就用来存放当前的工作线程.
    public  List<Thread> works=new ArrayList<> ();

    public  int MAX_WORKER_COUNT=10;

    //通过这个方法,把任务加入到线程池中
    //submit不光可以把任务放到阻塞队列中,也可以负责创建线程
    public  void submit(Runnable command) throws IOException, InterruptedException {
        if(works.size ()<MAX_WORKER_COUNT){
            //如果当前工作线程的数量不足线程数目上线,就创建出新的线程
            //工作线程就专门找一个类完成
            //worker内部要哦能够取到队列的内容,就要把这个队列实例通过worker的构造方法传过去
            Worker worker=new Worker (queue);
            worker.start ();
            works.add (worker);
        }
        queue.put (command);
    }
}

运行效果:

可以看到,打印了10个hello。

Comment implémenter la méthode de construction du pool de threads Java

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