

@RestControllerpublic class SeckillController { private static final ExecutorService executorService = new ThreadPoolExecutor( 100, 100, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<>(100) , new DefaultThreadFactory("kill-%d") , new ThreadPoolExecutor.CallerRunsPolicy()); private static final String SKU_NAME = "牛奶"; @Autowired private RedissonClient redissonClient; @Autowired private SeckillService seckillService; @GetMapping("/setStock") public String setStock() { // 将库存设置到信号量中 // 指定默认值是 100 boolean ok = redissonClient.getSemaphore(SKU_NAME).trySetPermits(100); if (ok) { return "库存已设置成功:100"; } else { return "库存设置失败"; } } /** * 秒杀小功能,利用redis作为分布式锁,使用信号量来进行库存的扣减 */ @GetMapping("/kill") public void kill() { for (int i = 0; i < 200; i++) { int num = (int) (Math.random() * 10 + 1); executorService.execute(() -> { boolean kill = seckillService.kill(SKU_NAME, num); if (kill) { System.out.println(Thread.currentThread().getName() + ":秒杀成功,买了" + num + "个"); // 业务处理,用户买了 几个skuName // 下单,发送消息到订单系统 } else { System.out.println(Thread.currentThread().getName() + ":想买" + num + "个,但秒杀失败"); } }); } // 秒杀结束,删除信号量 redissonClient.getSemaphore(SKU_NAME).delete(); }}
@Servicepublic class SeckillService { @Autowired private RedissonClient redissonClient; public boolean kill(String skuName, Integer num) { return redissonClient.getSemaphore(skuName).tryAcquire(num); }}