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
结果结果如下