SpringBoot+Redis隊列實現(xiàn)Java版秒殺的示例代碼
項目場景:
需求是做一個秒殺系統(tǒng),比如大家來搶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; //添加字符串并設(shè)置過期時間 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); } //根據(jù)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); } }
主要使用的是最后兩個方法,最后一個方法,在隊列頭部新增對象,如果沒有這個隊列,他會創(chuàng)建出來這個隊列,然后將一個集合統(tǒng)統(tǒng)塞到這個redis隊列中。倒數(shù)第二個方法每調(diào)用一次,會刪除隊列中最后一個元素,然后返回這個元素的值,如果隊列中已經(jīng)沒有元素了(隊列已經(jīng)沒了)那么他會返回null,他們都是原子操作。
如此,每個請求都無需經(jīng)過加鎖操作,直接利用redis的單線程特性,即可實現(xiàn)高并發(fā)下的秒殺:請求到達(dá)redis,redis會逐個執(zhí)行,每一次執(zhí)行要么返回一個值,要么返回null。很顯然,返回值的就是搶到了,返回null的就是沒搶到。而且可以靈活的為這個隊列新加入一些元素(老板發(fā)話再加100臺)或者直接把這個隊列刪了(老板說不行,不賣了)都不會對代碼產(chǎn)生任何影響。
其中對應(yīng)的redis操作指令分別是:
- 在隊列左側(cè)新增:lpush
- 在隊列右側(cè)消費:rpop
在任務(wù)開始時向redis中插入一個大隊列
List<String> entriesList = new LinkedList<>(); for (int i = 0; i < 100; i++){ entriesList.add("某個商品"); } redisService.addEntriesOnListLeft("隊列名",entriesList);
突然想到這個實現(xiàn)即使秒殺100臺不同型號的手機(并且在秒到時就通知用戶秒到的是啥),也不用改代碼。
每次秒殺執(zhí)行:
String redisResult = redisService.removeOneEntryOnListRight("隊列名"); if (null == redisResult) { //說明沒搶到 }else{ //說明搶到了 執(zhí)行搶到邏輯 }
到此這篇關(guān)于SpringBoot+Redis隊列實現(xiàn)Java版秒殺的示例代碼的文章就介紹到這了,更多相關(guān)SpringBoot Redis秒殺內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java對象級別與類級別的同步鎖synchronized語法示例
這篇文章主要為大家介紹了Java對象級別與類級別的同步鎖synchronized語法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-03-03Eureka注冊不上或注冊后IP不對(多網(wǎng)卡的坑及解決)
這篇文章主要介紹了Eureka注冊不上或注冊后IP不對(多網(wǎng)卡的坑及解決),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-11-11在 Spring Boot 項目中實現(xiàn)文件下載功能
這篇文章主要介紹了在 Spring Boot 項目中實現(xiàn)文件下載功能,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2019-09-09SpringBoot如何配置Controller實現(xiàn)Web請求處理
這篇文章主要介紹了SpringBoot如何配置Controller實現(xiàn)Web請求處理,文中通過圖解示例介紹的很詳細(xì),具有有一定的參考價值,需要的小伙伴可以參考一下2023-05-05Spring Boot jar可執(zhí)行原理的徹底分析
這篇文章主要給大家介紹了關(guān)于Spring Boot jar可執(zhí)行原理的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Spring Boot具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07Java中HashMap和Hashtable的區(qū)別淺析
這篇文章主要介紹了Java中HashMap和Hashtable的區(qū)別淺析,本文總結(jié)了6條它們之間的不同之處,需要的朋友可以參考下2015-03-03Linux下Java開發(fā)環(huán)境搭建以及第一個HelloWorld
這篇文章主要介紹了Linux下Java開發(fā)環(huán)境搭建以及第一個HelloWorld的實現(xiàn)過程,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2015-09-09Java多線程并發(fā)之線程池任務(wù)請求攔截測試實例
這篇文章主要介紹了Java多線程并發(fā)之線程池任務(wù)請求攔截測試實例,隊列中永遠(yuǎn)沒有線程被加入,即使線程池已滿,也不會導(dǎo)致被加入排隊隊列,實現(xiàn)了只有線程池存在空閑線程的時候才會接受新任務(wù)的需求,需要的朋友可以參考下2023-12-12