Redis实现高并发抢购/秒杀功能

Redis实现高并发抢购/秒杀功能

新建一个java文件:Dome1.java
在这里插入图片描述在这里插入图片描述在这里插入图片描述

package com.example.demo;

import redis.clients.jedis.Jedis;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Dome1 {
    static Boolean isEmpty = false;

    public static void main(String[] args) {
        //模拟用户数量
        int userNumber = 100;
        //模拟从数据库读取商品数量
        int goodsNumber = 50;

        // TODO Auto-generated method stub
        //线程池,无限缓存线程池
        ExecutorService excutor = Executors.newCachedThreadPool();
        //连接本地的 Redis 服务
        Jedis jedis = new Jedis("localhost", 6379);
        String ping = jedis.ping();
        if (ping.equalsIgnoreCase("PONG")) {
            System.out.println("redis缓存有效!" + ping);
        }

        String value = jedis.get("goods");
        if(value == null){
            System.out.println("无商品数据,开始添加!");
            //插入100个商品
            for(int i = 0;i<goodsNumber;i++){
                jedis.lpush("goods", ""+i);
            }
        }

        //TODO 还要保证同一个用户不能秒杀两个
        Map<String,String> map = new HashMap<>();
        long length = jedis.llen("goods");//列表长度
        System.out.println("商品剩余数量:"+length);
        //模拟秒杀代码
        CountDownLatch countDown = new CountDownLatch(userNumber);
        for (int i = 0; i < userNumber; i++) {
            final int index = i;
            excutor.execute( () ->{
                System.out.println("用户 "+index+" 开始秒杀商品!");
                //如果已经被抢完则直接拒绝后面的请求了。
                if(isEmpty){
                    System.out.println("用户"+index+" 抱歉商品已抢走!");
                    countDown.countDown();
                    return;
                }
                Jedis checkJedis = new Jedis("localhost");
                String result = checkJedis.lpop("goods");//Redis Lpop 命令用于移除并返回列表的第一个元素
                //如果成功删除redis里的数据则表示抢到,如果存储数字则还需要事务控制并修改商品数字,比较影响性能,因此使用list比较好。
                if(result!=null&&!result.equals("")){
                    System.out.println("用户 "+ index+" 成功抢到商品!");
                    map.put(index+"", result);
                }else{
                    //只允许一个线程修改状态
                    synchronized (isEmpty) {
                        isEmpty = true;
                    }
                    System.out.println("用户 "+index+" 很遗憾你没有抢到,该商品已被抢完。");
                }
                checkJedis.close();
                //表示一个线程执行完毕了
                countDown.countDown();
            });
        }
        try {
            //等待所有线程执行完毕
            countDown.await();
            System.out.println("所有用户秒杀完毕,开始公布结果:");
            for (String key : map.keySet()) {
                System.out.println("恭喜用户"+key+" 成功抢到商品!");
            }
            System.out.println("共"+map.size()+"位用户成功抢到。");
            jedis.close();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("程序结束");
    }


}

运行main()方法
在这里插入图片描述
实现效果
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值