亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁技術文章
文章詳情頁

Java使用Redis實現秒殺功能

瀏覽:2日期:2022-08-23 14:24:44

秒殺功能

秒殺場景現在已經非常常見了,各種電商平臺都有秒殺的產品,接下來我們模擬一個秒殺的項目,最終能夠確保高并發下的線程安全。界面比較簡單,但是功能基本實現。

界面

Java使用Redis實現秒殺功能

點擊“秒殺點我”按鈕后臺就會輸出秒殺結果。

Java使用Redis實現秒殺功能

第一版

使用Redis緩存數據庫,使用一個key-value存儲秒殺商品數量,使用set集合存儲秒殺成功的用戶。我們以商品0101為示例,設置商品的初始數量為200件。不考慮并發問題,實現功能。

html、jsp、servlet文件不重要省略。

package com.redis.secondskill; import java.util.List; import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisPool;import redis.clients.jedis.Transaction; public class SS0 { public static boolean doSecKill(String uid,String prodid) { JedisPool jedisPool = JedisPollTool.getInstance(); Jedis jedis = jedisPool.getResource(); String productCountStr = 'sec:'+prodid+':count'; String productUserStr = 'sec:'+prodid+':user'; String productCount = jedis.get(productCountStr); if(null == productCount) { System.out.println('秒殺還沒有開始'); JedisPollTool.distroy(jedisPool, jedis); return false; } if(jedis.sismember(productUserStr, uid)) { System.out.println(uid + '用戶已經秒殺成功'); JedisPollTool.distroy(jedisPool, jedis); return false; } int prodCount = Integer.parseInt(productCount); if(prodCount <= 0) { System.out.println('秒殺結束'); JedisPollTool.distroy(jedisPool, jedis); return false; } jedis.decr(productCountStr); jedis.sadd(productUserStr, uid); JedisPollTool.distroy(jedisPool, jedis); System.out.println(uid + '秒殺成功'); return true; }}

使用linux httpd-tools工具進行并發測試。

ab -n 1000 -c 200 -p /test/file.txt -T 'application/x-www-form-urlencoded' 192.168.0.101:8080/redis-demo/ss

結果

Java使用Redis實現秒殺功能

從結果大致來看,沒有什么問題,來查看一個后臺Redis的數據

秒殺的結果里面居然有負數,證明賣超了。

Java使用Redis實現秒殺功能

第二版

使用Redis的事務,保證沒有超賣的情況發生。

package com.redis.secondskill; import java.util.List; import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisPool;import redis.clients.jedis.Transaction; public class SS1 { public static boolean doSecKill(String uid,String prodid) { JedisPool jedisPool = JedisPollTool.getInstance(); Jedis jedis = jedisPool.getResource(); String productCountStr = 'sec:'+prodid+':count'; String productUserStr = 'sec:'+prodid+':user'; jedis.watch(productCountStr); //開始監視 String productCount = jedis.get(productCountStr); if(null == productCount) { System.out.println('秒殺還沒有開始'); JedisPollTool.distroy(jedisPool, jedis); return false; } if(jedis.sismember(productUserStr, uid)) { System.out.println(uid + '用戶已經秒殺成功'); JedisPollTool.distroy(jedisPool, jedis); return false; } int prodCount = Integer.parseInt(productCount); if(prodCount <= 0) { System.out.println('秒殺結束'); JedisPollTool.distroy(jedisPool, jedis); return false; } Transaction transaction = jedis.multi(); transaction.decr(productCountStr); transaction.sadd(productUserStr, uid); List<Object> exec = transaction.exec(); if(exec == null || exec.size() == 0) { System.out.println('秒殺失敗,稍后重試'); JedisPollTool.distroy(jedisPool, jedis); return false; } JedisPollTool.distroy(jedisPool, jedis); System.out.println(uid + '秒殺成功'); return true; }}

結果

Java使用Redis實現秒殺功能

由于使用了watch和事務,每次的并發線程訪問中只有一個線程能夠提交成功,可以保證不出現超賣的現象,但是對于一些用戶來說是極其不公平的。

第三版

使用Lua腳本來實現,因為Redis是單線程的,又是C語言編寫的,可以使用Lua調用Redis的命令,Lua會具有排他性,所以能夠保證安全。

package com.redis.secondskill; import java.util.HashSet;import java.util.Set; import redis.clients.jedis.HostAndPort;import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisPool; public class SS2 { static String luaScript ='local userid=KEYS[1];rn' + 'local prodid=KEYS[2];rn' + 'local qtkey=’sec:’..prodid..':count';rn' + 'local usersKey=’sec:’..prodid..':user';rn' + 'local userExists=redis.call('sismember',usersKey,userid);rn' + 'if tonumber(userExists)==1 then rn' + ' return 2;rn' + 'endrn' + 'local num = redis.call('get' ,qtkey);rn' + 'if tonumber(num)<=0 then rn' + ' return 0;rn' + 'else rn' + ' redis.call('decr',qtkey);rn' + ' redis.call('sadd',usersKey,userid);rn' + 'endrn' + 'return 1' ; public static boolean doSecKill(String uid,String prodid) { JedisPool jedisPool = JedisPollTool.getInstance(); Jedis jedis = jedisPool.getResource(); String sha1 = jedis.scriptLoad(luaScript); Object result= jedis.evalsha(sha1, 2, uid,prodid); String reString=String.valueOf(result); if ('0'.equals( reString ) ) { System.err.println('已搶空!!'); }else if('1'.equals( reString ) ) { System.out.println(uid + '搶購成功!!!!'); }else if('2'.equals( reString ) ) { System.err.println('該用戶已搶過!!'); }else{ System.err.println('搶購異常!!'); } JedisPollTool.distroy(jedisPool, jedis); return true; }}

結果

Java使用Redis實現秒殺功能

這才是我們最希望看到的結果!

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持好吧啦網。

標簽: Java
相關文章:
主站蜘蛛池模板: 99久久免费国产精品 | aaa大片 | 无套国产 | 国产成人精品亚洲2020 | 黑人一级大毛片 | 青草视频在线观看免费视频 | 精品国产一区二区三区成人 | 午夜特片网 | 精品一区在线 | 亚洲日韩成人 | 国产一级aa大片毛片 | 无码中文字幕日韩专区 | 日产国产欧美视频一区精品 | 成年视频xxxxx在线入口 | 青青国产成人久久91网站站 | 青青青视频精品中文字幕 | 日本黄色大片免费 | 一品毛片| 欧美片免费观看网址 | 中文字幕在线观看一区 | 1024 cc香蕉在线观看看中文 | 中国高清性色生活片 | 亚洲一级特黄 | 一区二区三区四区日韩 | 久久六月丁香婷婷婷 | 美美女高清毛片视频黄的一免费 | 8x永久免费观看成人影院 | 伊人丁香花久久爱综合 | a级在线观看视频 | 中文 国产 亚洲 喷潮 | 亚洲免费中字慕日产2021 | 热99re久久精品这里都是免费 | 日韩久草 | 正在播放宾馆露脸对白视频 | 国产美女一级特黄毛片 | 黄片毛片大全 | 日本一级级特黄特色大片 | 亚洲国产第一区 | 久久精品免视看国产明星 | 97影院午夜午夜伦不卡 | 天天在线天天综合网色 |