redis实现秒杀抢票功能
一,前言
实践是检验真理的唯一标准,纸上得来终觉浅嘛!想认识一个人,光靠个人资料怎么行,哪怕见面聊上那么一两句,那也是会产生很多偶然性的结果,俗话说,患难见真情,当然,此处不是让你去患难,而是和redis进行一个简单的交互,那其中机理虽不说详识,但大致什么样子和总体印象还是会有的。话不多说,撸起袖子就是干!
二,具体操作
1,打开eclipse,新建Maven工程,
2,额外导入jar包:
<!-- redis工具包 -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.0.1</version>
</dependency>
3,代码不多,就两个类
(1)MyRedisTest.java
package com.spring.server.redis;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import redis.clients.jedis.Jedis;
public class MyRedisTest {
public static void main(String args[]){
final String watchKeys = "watchKeys";
ExecutorService executor = Executors.newFixedThreadPool(20);//20个线程池并发。
final Jedis jedis = new Jedis("127.0.0.1",6379);
System.out.println(jedis.get("myKey"));
jedis.set(watchKeys,"100");//设置起始的抢购数。
jedis.close();
for(int i = 0; i < 1000; i++){//设置1000个人来发起抢购
executor.execute(new MyRunnable("user"+getRandomString(6)));
}
executor.shutdown();
}
private static String getRandomString(int length) {//length是随机字符串长度
String base = "abcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random();
StringBuffer sb = new StringBuffer();
for(int i = 0; i<length; i++){
//该方法的作用是生成一个随机的int值,该值介于[0,n)的区间,也就是0到n之间的随机int值,包含0而不包含n。
int number = random.nextInt(base.length());
//charAt() 方法用于返回指定索引处的字符。索引范围为从 0 到 length() - 1。
sb.append(base.charAt(number));
}
return sb.toString();
}
}
(2)MyRunnable.java
package com.spring.server.redis;
import java.util.List;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
public class MyRunnable implements Runnable {
String watchKeys = "watchKeys";//监视keys
Jedis jedis = new Jedis("127.0.0.1",6379);
String userInfo;
public void myRunnable(){
}
public MyRunnable(String uinfo){
this.userInfo = uinfo;
}
@Override
public void run() {
try{
jedis.watch(watchKeys);
String val = jedis.get(watchKeys);
int valint = Integer.valueOf(val);
if(valint <= 100 && valint >=1){
Transaction tx = jedis.multi();//开启事务
tx.incrBy("watchKeys",-1);
List<Object> list = tx.exec();//提交事务,如果此时watchKeys被改动了,则返回null
if(list == null || list.size()==0){
String failuserifo = "fail"+userInfo;
String failinfo="用户:" + failuserifo + "商品争抢失败,抢购失败";
System.out.println(failinfo);
/* 抢购失败业务逻辑 */
jedis.setnx(failuserifo, failinfo);
}else{
for(Object succ : list){
String succuserifo ="succ"+succ.toString() +userInfo ;
String succinfo="用户:" + succuserifo + "抢购成功,当前抢购成功人数:"
+ (1-(valint-100));
System.out.println(succinfo);
/* 抢购成功业务逻辑 */
jedis.setnx(succuserifo, succinfo);
}
}
}else{
String failuserifo = "kcfail" + userInfo;
String failinfo1="用户:" + failuserifo + "商品被抢购完毕,抢购失败";
System.out.println(failinfo1);
jedis.setnx(failuserifo, failinfo1);
// Thread.sleep(500);
return;
}
}catch(Exception e){
e.printStackTrace();
}finally{
jedis.close();
}
}
}
4,点击运行
OK! 到这,与redis的互动结束了,你有什么收获呢?