Le pool de threads Java réalise la fonction de pointe

1. Présentation du pool de threads

Thread pool (anglais: thread pool): Il s'agit d'une forme de traitement multi-thread dans laquelle des tâches sont ajoutées à la file d'attente pendant le traitement, puis ces tâches sont automatiquement démarrées après la création des threads. Les threads de pool de threads sont des threads d'arrière-plan. Chaque thread utilise la taille de pile par défaut, s'exécute avec la priorité par défaut et se trouve dans une unité multi-thread. Si un thread est inactif dans le code managé (comme l'attente d'un événement), le pool de threads insère un autre thread auxiliaire pour garder tous les processeurs occupés. Si tous les threads du pool de threads sont toujours occupés, mais que la file d'attente contient du travail en attente, le pool de threads créera un autre thread auxiliaire après un certain temps, mais le nombre de threads ne dépassera jamais le maximum. Les threads qui dépassent le maximum peuvent être mis en file d'attente, mais ils ne démarreront pas tant que les autres threads ne seront pas terminés.

Voici les supports d'apprentissage que j'ai rassemblés sur Internet sur le multithreading Java et le pool de threads.

Matériel didactique 1: "Java Multithreading"

Matériel didactique 2: "Java thread pool ExecutorService"

Matériel d'apprentissage 3: "Classe de pool de threads Java ThreadPoolExecutor, ScheduledThreadPoolExecutor et classe d'usine Executors"

Matériel didactique 4: "Le pool de threads Java réalise la fonction de pointe"

 

2. Le pool de threads Java réalise la fonction de pointe

[Exemple] Java utilise le multi-threading et Redis pour créer une instance où 1 000 personnes tuent 100 téléphones mobiles en quelques secondes.

(1) Implémentation SecondKill (SecondKill.java): Créez plusieurs threads et utilisez la fonction de transaction de Redis pour réaliser la deuxième fonction kill.

package com.pjb.seckill;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
import java.util.List;

/**
 * 秒杀抢购
 * @author pan_junbiao
 **/
public class SecondKill implements Runnable
{

    String iphone = "iphone";
    Jedis jedis = new Jedis("127.0.0.1",6379);
    String userInfo;

    public SecondKill(String userInfo)
    {
        this.userInfo = userInfo;
    }

    @Override
    public void run()
    {
        try
        {
            jedis.watch(iphone); //watchkeys

            String val = jedis.get(iphone);
            int valint = Integer.valueOf(val);

            if(valint<=100 && valint>=1)
            {
                //1、使用MULTI命令开启事务
                Transaction tx = jedis.multi();

                //2、事务命令入队
                tx.incrBy("iphone",-1);

                //3、使用EXEC命令执行事务
                //提交事务。如果此时watchkeys被改动了,则返回null
                List<Object> list = tx.exec();

                if(list==null || list.size()==0)
                {
                    String failuserinfo = "fail_" + userInfo;
                    String failinfo = "用户:" + failuserinfo + "商品争抢失败,抢购失败";
                    System.out.println(failinfo);
                    //抢购失败业务逻辑
                    jedis.setnx(failuserinfo,failinfo);
                }
                else
                {
                    for(Object succ : list)
                    {
                        String succuserinfo = "succ_" + succ.toString() + "_" + userInfo;
                        String succinfo = "用户:" + succuserinfo + " 抢购成功,当前抢购成功人数:" + (1 -(valint -100));
                        System.out.println(succinfo);
                        //抢购成功业务逻辑
                        jedis.setnx(succuserinfo,succinfo);
                    }
                }
            }
            else
            {
                String failuserinfo = "kcfail_" + userInfo;
                String failinfo1 = "用户:" + failuserinfo + " 商品被抢购完毕,抢购失败";
                System.out.println(failinfo1);
                jedis.setnx(failuserinfo,failinfo1);
                //Thread.sleep(500);
                return;
            }
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
        finally
        {
            jedis.close();
        }
    }
}

(2) Programme principal (SecondKillTest.java): le programme d'entrée de la fonction de pointe, utilisé pour créer un pool de threads, générer un ID utilisateur en même temps, appeler le code de la fonction de pointe et terminer la tâche de pointe.

package com.pjb.seckill;

import com.pjb.util.RedisHelper;
import org.springframework.beans.factory.annotation.Autowired;
import redis.clients.jedis.Jedis;

import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Redis秒杀功能的实现,1000人抢购100部手机
 * @author pan_junbiao
 **/
public class SecondKillTest
{
    public static void main(String[] args)
    {
         RedisHelper redisHelper = new RedisHelper();

        final String iphone = "iphone";
        //20个线程池并发数
        ExecutorService executor = Executors.newFixedThreadPool(20);

        final Jedis jedis = new Jedis("127.0.0.1",6379);
        jedis.del(iphone); //先删除
        jedis.set(iphone,"100"); //设置起始的抢购数
        jedis.close();

        for(int i=0; i<1000; i++)
        {
            String userInfo = "pan_junbiao的博客" + i;
            executor.execute(new SecondKill(userInfo));
        }
        executor.shutdown();
    }
}

Résultats de la:

 

3. Le pool de threads Java réalise la fonction de chronométrage des tâches

[Exemple] Java utilise java.util.concurrent.ScheduledExecutorService pour implémenter des tâches de minutage.

package com.pjb.seckill;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 使用ScheduledExecutorService实现定时任务
 * @author pan_junbiao
 */
public class Task
{
    public static void main(String[] args)
    {
        //1、创建线程任务
        Runnable runnable = new Runnable()
        {
            public void run()
            {
                System.out.println("您好,欢迎访问 pan_junbiao的博客");
            }
        };

        //2、创建线程池
        ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();

        //3、线程池绑定线程任务并执行(第二个参数为首次执行的延时时间,第三个参数为定时执行的间隔时间)
        service.scheduleAtFixedRate(runnable, 10, 1, TimeUnit.SECONDS);
    }
}

Résultats de la:

 

Je suppose que tu aimes

Origine blog.csdn.net/pan_junbiao/article/details/110236480
conseillé
Classement