image.png
    image.png

    1. @RestController
    2. public class SeckillController {
    3. private static final ExecutorService executorService = new ThreadPoolExecutor(
    4. 100,
    5. 100,
    6. 10,
    7. TimeUnit.SECONDS,
    8. new LinkedBlockingQueue<>(100)
    9. , new DefaultThreadFactory("kill-%d")
    10. , new ThreadPoolExecutor.CallerRunsPolicy());
    11. private static final String SKU_NAME = "牛奶";
    12. @Autowired
    13. private RedissonClient redissonClient;
    14. @Autowired
    15. private SeckillService seckillService;
    16. @GetMapping("/setStock")
    17. public String setStock() {
    18. // 将库存设置到信号量中
    19. // 指定默认值是 100
    20. boolean ok = redissonClient.getSemaphore(SKU_NAME).trySetPermits(100);
    21. if (ok) {
    22. return "库存已设置成功:100";
    23. } else {
    24. return "库存设置失败";
    25. }
    26. }
    27. /**
    28. * 秒杀小功能,利用redis作为分布式锁,使用信号量来进行库存的扣减
    29. */
    30. @GetMapping("/kill")
    31. public void kill() {
    32. for (int i = 0; i < 200; i++) {
    33. int num = (int) (Math.random() * 10 + 1);
    34. executorService.execute(() -> {
    35. boolean kill = seckillService.kill(SKU_NAME, num);
    36. if (kill) {
    37. System.out.println(Thread.currentThread().getName() + ":秒杀成功,买了" + num + "个");
    38. // 业务处理,用户买了 几个skuName
    39. // 下单,发送消息到订单系统
    40. } else {
    41. System.out.println(Thread.currentThread().getName() + ":想买" + num + "个,但秒杀失败");
    42. }
    43. });
    44. }
    45. // 秒杀结束,删除信号量
    46. redissonClient.getSemaphore(SKU_NAME).delete();
    47. }
    48. }
    1. @Service
    2. public class SeckillService {
    3. @Autowired
    4. private RedissonClient redissonClient;
    5. public boolean kill(String skuName, Integer num) {
    6. return redissonClient.getSemaphore(skuName).tryAcquire(num);
    7. }
    8. }