springboo单机多线程高并发防止重复消费的redis方案
仅提供方案与测试。
想法:第一次收到userCode时,检查是否在redis中有,如果有,就表明已经消费了,返回抢单失败;否则,就去消费,顺便写入redis缓存中。
1、单独做redis锁,测试(失败案例)
public static int countNum = 0;
public static int countFailNum = 0;
@Anonymous
@GetMapping("/testRedis")
public AjaxResult testRedis(String userCode){
String key = "sign:"+userCode;
if (redisCache.hasKey(key)){
++countFailNum;
System.out.println("抢单成功,人数是"+countNum+" | 抢单失败的人数是"+countFailNum);
return AjaxResult.error("抢单失败");
}
redisCache.setCacheObject(key,userCode,10, TimeUnit.MINUTES);
++countNum;
System.out.println("抢单成功,人数是"+countNum+" | 抢单失败的人数是"+countFailNum);
return AjaxResult.success("抢单成功,人数是"+countNum);
}
很明显,单纯的redis,根本扛不住基础的并发请求
2、线程锁+redis锁,测试(正确方案)
给方法加线程锁 关键字:synchronized
结果结果如下