Der Java-Thread-Pool realisiert die Spike-Funktion

1. Einführung in den Thread-Pool

Thread-Pool (Englisch: Thread-Pool): Dies ist eine Form der Multithread-Verarbeitung, bei der Aufgaben während der Verarbeitung zur Warteschlange hinzugefügt werden. Diese Aufgaben werden dann automatisch gestartet, nachdem Threads erstellt wurden. Thread-Pool-Threads sind Hintergrund-Threads. Jeder Thread verwendet die Standardstapelgröße, wird mit der Standardpriorität ausgeführt und befindet sich in einer Multithread-Einheit. Wenn ein Thread im verwalteten Code inaktiv ist (z. B. auf ein Ereignis wartet), fügt der Thread-Pool einen weiteren Hilfsthread ein, um alle Prozessoren zu beschäftigen. Wenn alle Thread-Pool-Threads immer ausgelastet sind, die Warteschlange jedoch ausstehende Arbeiten enthält, erstellt der Thread-Pool nach einer bestimmten Zeit einen weiteren Hilfsthread, die Anzahl der Threads überschreitet jedoch niemals das Maximum. Threads, die das Maximum überschreiten, können in die Warteschlange gestellt werden. Sie werden jedoch erst gestartet, wenn die anderen Threads fertig sind.

Im Folgenden sind die Lernmaterialien aufgeführt, die ich im Internet über Java-Multithreading und Thread-Pool gesammelt habe.

Lernmaterialien 1: "Java Multithreading"

Lernmaterialien 2: "Java-Thread-Pool ExecutorService"

Lernmaterialien 3: "Java-Thread-Pool-Klasse ThreadPoolExecutor, ScheduledThreadPoolExecutor und Executors-Factory-Klasse"

Lernmaterialien 4: "Java-Thread-Pool realisiert die Spike-Funktion"

 

2. Der Java-Thread-Pool realisiert die Spike-Funktion

[Beispiel] Java verwendet Multithreading und Redis, um eine Instanz zu erreichen, in der 1000 Menschen 100 Mobiltelefone in Sekunden töten.

(1) SecondKill-Implementierung (SecondKill.java): Erstellen Sie mehrere Threads und verwenden Sie die Transaktionsfunktion von Redis, um die zweite Kill-Funktion zu realisieren.

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) Hauptprogramm (SecondKillTest.java): Das Eingabeprogramm der Spike-Funktion, mit dem ein Thread-Pool erstellt, gleichzeitig eine Benutzer-ID generiert, der Spike-Funktionscode aufgerufen und die Spike-Aufgabe abgeschlossen wird.

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

Ergebnisse der:

 

3. Der Java-Thread-Pool realisiert die Funktion von Timing-Aufgaben

[Beispiel] Java verwendet java.util.concurrent.ScheduledExecutorService, um Timing-Aufgaben zu implementieren.

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

Ergebnisse der:

 

Ich denke du magst

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