O pool de threads do Java realiza a função de pico

1. Introdução ao pool de threads

Pool de threads (inglês: pool de threads): É uma forma de processamento multi-threaded no qual as tarefas são adicionadas à fila durante o processamento e, em seguida, essas tarefas são iniciadas automaticamente após a criação dos threads. Os threads do pool de threads são threads em segundo plano. Cada thread usa o tamanho de pilha padrão, é executado na prioridade padrão e está em uma unidade multi-threaded. Se um encadeamento estiver ocioso no código gerenciado (como aguardando um evento), o pool de encadeamentos inserirá outro encadeamento auxiliar para manter todos os processadores ocupados. Se todos os threads do pool de threads estiverem sempre ocupados, mas a fila contiver trabalho pendente, o pool de threads criará outro thread auxiliar após um período de tempo, mas o número de threads nunca excederá o máximo. Threads que excedem o máximo podem ser enfileirados, mas não iniciarão até que os outros threads sejam concluídos.

A seguir estão os materiais de aprendizagem que coletei na Internet sobre multithreading Java e pool de threads.

Materiais de aprendizagem 1: "Java Multithreading"

Materiais de aprendizagem 2: "Java thread pool ExecutorService"

Materiais de aprendizagem 3: "Classe de pool de threads Java ThreadPoolExecutor, ScheduledThreadPoolExecutor e classe de fábrica Executors"

Materiais de aprendizagem 4: "O pool de threads Java realiza a função de pico"

 

2. O pool de threads Java realiza a função de pico

[Exemplo] Java usa multi-threading e Redis para atingir uma instância em que 1000 pessoas matam 100 telefones celulares em segundos.

(1) Implementação de SecondKill (SecondKill.java): Crie vários threads e use a função de transação do Redis para realizar a segunda função de eliminação.

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) Programa principal (SecondKillTest.java): o programa de entrada da função spike, usado para criar um pool de threads, gerar ID do usuário ao mesmo tempo, chamar o código da função spike e concluir a tarefa spike.

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

Resultados de:

 

3. O pool de threads Java realiza a função de tarefas de cronometragem

[Exemplo] Java usa java.util.concurrent.ScheduledExecutorService para implementar tarefas de temporização.

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

Resultados de:

 

Acho que você gosta

Origin blog.csdn.net/pan_junbiao/article/details/110236480
Recomendado
Clasificación