国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java使用Redis實現秒殺功能

Java使用Redis實現秒殺功能

2020-09-30 00:24楚瑞濤 Java教程

這篇文章主要為大家詳細介紹了Java使用Redis實現秒殺功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

秒殺功能

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

界面

Java使用Redis實現秒殺功能

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

Java使用Redis實現秒殺功能

第一版

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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的事務,保證沒有超賣的情況發生。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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會具有排他性,所以能夠保證安全。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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];\r\n" +
 "local prodid=KEYS[2];\r\n" +
 "local qtkey='sec:'..prodid..\":count\";\r\n" +
 "local usersKey='sec:'..prodid..\":user\";\r\n" +
 "local userExists=redis.call(\"sismember\",usersKey,userid);\r\n" +
 "if tonumber(userExists)==1 then \r\n" +
 " return 2;\r\n" +
 "end\r\n" +
 "local num = redis.call(\"get\" ,qtkey);\r\n" +
 "if tonumber(num)<=0 then \r\n" +
 " return 0;\r\n" +
 "else \r\n" +
 " redis.call(\"decr\",qtkey);\r\n" +
 " redis.call(\"sadd\",usersKey,userid);\r\n" +
 "end\r\n" +
 "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實現秒殺功能

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

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://blog.csdn.net/cong____cong/article/details/105566983

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 青青在线精品视频 | 久久视频在线 | 五月宗合网 | 免费黄色网止 | 日本在线一区二区三区 | 欧美一区二区三区免费观看视频 | 国产四区 | 久久综合成人精品亚洲另类欧美 | www.一区 | 久久精品无码一区二区三区 | 精品国产91亚洲一区二区三区www | 特黄特黄的视频 | 羞羞视频免费观看网站 | 久久久精品一区二区三区 | 成人3d动漫一区二区三区91 | 久久久性色精品国产免费观看 | 一区二区三区四区日韩 | 午夜在线小视频 | 国产精品亚洲视频 | 久久久无码精品亚洲日韩按摩 | 人成免费在线视频 | 亚洲福利一区二区 | 五月婷婷网站 | 国产精品视频一二三区 | 国产精品精品视频一区二区三区 | 日本中文字幕在线观看 | 亚洲精品免费在线观看 | 一区二区久久久 | 欧美色综合天天久久综合精品 | 国产在线a | 久久久亚洲国产天美传媒修理工 | 国产91精品亚洲精品日韩已满 | 日韩精品一区二区三区中文在线 | 五月婷婷在线观看视频 | 成人在线免费观看视频 | 亚洲精品电影在线观看 | 久久网页 | 亚洲精品久久久久久下一站 | 亚洲精品乱码 | 在线观看黄免费 | 亚洲国内精品 |