Java thread pool realizes spike function

1. Introduction to thread pool

Thread pool (English: thread pool): It is a form of multi-threaded processing in which tasks are added to the queue during processing, and then these tasks are automatically started after threads are created. Thread pool threads are background threads. Each thread uses the default stack size, runs at the default priority, and is in a multi-threaded unit. If a thread is idle in managed code (such as waiting for an event), the thread pool will insert another auxiliary thread to keep all processors busy. If all thread pool threads are always busy, but the queue contains pending work, the thread pool will create another auxiliary thread after a period of time but the number of threads will never exceed the maximum. Threads that exceed the maximum can be queued, but they will not start until the other threads are finished.

The following are the learning materials I collected on the Internet about Java multithreading and thread pool.

Learning materials 1: "Java Multithreading"

Learning materials 2: "Java thread pool ExecutorService"

Learning materials 3: "Java thread pool class ThreadPoolExecutor, ScheduledThreadPoolExecutor and Executors factory class"

Learning materials 4: "Java thread pool realizes the spike function"

 

2. Java thread pool realizes the spike function

[Example] Java uses multi-threading and Redis to achieve an instance where 1000 people kill 100 mobile phones in seconds.

(1) SecondKill implementation (SecondKill.java): Create multiple threads and use Redis' transaction function to realize the second kill function.

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) Main program (SecondKillTest.java): the entry program of the spike function, used to create a thread pool, generate user ID at the same time, call the spike function code, and complete the spike task.

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

Results of the:

 

3. Java thread pool realizes the function of timing tasks

[Example] Java uses java.util.concurrent.ScheduledExecutorService to implement timing tasks.

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

Results of the:

 

Guess you like

Origin blog.csdn.net/pan_junbiao/article/details/110236480