@RestController
public 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();
}
}
@Service
public class SeckillService {
@Autowired
private RedissonClient redissonClient;
public boolean kill(String skuName, Integer num) {
return redissonClient.getSemaphore(skuName).tryAcquire(num);
}
}