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