SpringBoot+Redis队列实现Java版秒杀的示例代码

 更新时间:2023年06月09日 09:41:01   作者:可乐汉堡cola  
本文主要介绍了SpringBoot+Redis队列实现Java版秒杀的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

项目场景:

需求是做一个秒杀系统,比如大家来抢100台手机,先到先得。

解决方案:

这里用的是springboot的StringRedisTemplate

工具类:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import java.time.Duration;
import java.util.Collection;
@Service
public class RedisServiceImpl {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    //添加字符串并设置过期时间
    public void addString(String key, String value, Duration duration) {
        stringRedisTemplate.opsForValue().set(key, value, duration);
    }
    //查找字符串
    public String findString(String key) {
        return stringRedisTemplate.opsForValue().get(key);
    }
    //根据Key删除
    public Boolean deleteByKey(String key) {
        return stringRedisTemplate.delete(key);
    }
    //在队列尾部减少一个对象
    public String removeOneEntryOnListRight(String listName) {
        return stringRedisTemplate.opsForList().rightPop(listName);
    }
    //在队列头部新增对象
    public Long addEntriesOnListLeft(String listName, Collection<String> args) {
        return stringRedisTemplate.opsForList().leftPushAll(listName, args);
    }
}

主要使用的是最后两个方法,最后一个方法,在队列头部新增对象,如果没有这个队列,他会创建出来这个队列,然后将一个集合统统塞到这个redis队列中。倒数第二个方法每调用一次,会删除队列中最后一个元素,然后返回这个元素的值,如果队列中已经没有元素了(队列已经没了)那么他会返回null,他们都是原子操作。

如此,每个请求都无需经过加锁操作,直接利用redis的单线程特性,即可实现高并发下的秒杀:请求到达redis,redis会逐个执行,每一次执行要么返回一个值,要么返回null。很显然,返回值的就是抢到了,返回null的就是没抢到。而且可以灵活的为这个队列新加入一些元素(老板发话再加100台)或者直接把这个队列删了(老板说不行,不卖了)都不会对代码产生任何影响。

其中对应的redis操作指令分别是:

  • 在队列左侧新增:lpush
  • 在队列右侧消费:rpop

在任务开始时向redis中插入一个大队列

List<String> entriesList = new LinkedList<>();
   for (int i = 0; i < 100; i++){
       entriesList.add("某个商品");
   }
   redisService.addEntriesOnListLeft("队列名",entriesList);

突然想到这个实现即使秒杀100台不同型号的手机(并且在秒到时就通知用户秒到的是啥),也不用改代码。

每次秒杀执行:

String redisResult = redisService.removeOneEntryOnListRight("队列名");
    if (null == redisResult) {
        //说明没抢到
    }else{
 //说明抢到了 执行抢到逻辑
}

到此这篇关于SpringBoot+Redis队列实现Java版秒杀的示例代码的文章就介绍到这了,更多相关SpringBoot Redis秒杀内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java Instrumentation从概念到基本用法详解

    Java Instrumentation从概念到基本用法详解

    Java Instrumentation是java.lang.instrument包提供的 API,允许开发者在类被JVM 加载时对其进行修改,或者在运行时重新定义类的字节码,本文给大家介绍Java Instrumentation从概念到基本用法详解,感兴趣的朋友一起看看吧
    2025-09-09
  • Spring的@Autowired加到接口上但获取的是实现类的问题

    Spring的@Autowired加到接口上但获取的是实现类的问题

    这篇文章主要介绍了Spring的@Autowired加到接口上但获取的是实现类的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10
  • Spring Cloud引入Eureka组件,完善服务治理

    Spring Cloud引入Eureka组件,完善服务治理

    这篇文章主要介绍了Spring Cloud引入Eureka组件,完善服务治理的过程详解,帮助大家更好的理解和使用spring cloud,感兴趣的朋友可以了解下
    2021-02-02
  • JavaWeb实现邮件发送功能

    JavaWeb实现邮件发送功能

    这篇文章主要为大家详细介绍了JavaWeb实现邮件发送功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-12-12
  • Java实现base64图片编码数据转换为本地图片的方法

    Java实现base64图片编码数据转换为本地图片的方法

    这篇文章主要介绍了Java实现base64图片编码数据转换为本地图片的方法,涉及java编码转换及图片文件生成相关操作技巧,需要的朋友可以参考下
    2018-06-06
  • Java线程池运行状态监控实现解析

    Java线程池运行状态监控实现解析

    这篇文章主要介绍了Java线程池运行状态监控实现解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • SpringBoot加载SQLite数据源方式

    SpringBoot加载SQLite数据源方式

    文章介绍了SpringBoot中配置SQLite数据源的流程,包括DBeaver连接数据库、执行建表与数据插入、引入依赖、初始化连接、定义实体类与Mapper,以及测试查询操作,同时提及多数据源适配的扩展方式
    2025-09-09
  • MybatisPlus使用idworker解决雪花算法重复

    MybatisPlus使用idworker解决雪花算法重复

    本文主要介绍了MybatisPlus使用idworker解决雪花算法重复,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02
  • openjdk与Oraclejdk的区别

    openjdk与Oraclejdk的区别

    这篇文章主要介绍了openjdk与Oraclejdk的区别,帮助大家更好的了解JAVA,感兴趣的朋友可以了解下
    2020-08-08
  • SpringBoot实现文件记录日志及日志文件自动归档和压缩

    SpringBoot实现文件记录日志及日志文件自动归档和压缩

    Logback是Java日志框架,通过Logger收集日志并经Appender输出至控制台、文件等,SpringBoot配置logback-spring.xml可实现日志文件存储,本文给大家介绍了SpringBoot实现文件记录日志及日志文件自动归档和压缩,需要的朋友可以参考下
    2025-05-05

最新评论