Redis实现分布式锁的简单例子

废话不多说,直接看代码。

public String lock(Goods goods, Long goodsCount) {
        // 先去尝试给 redis 加锁
        String id = String.valueOf(goods.getGoodsId());
        ValueOperations<String, String> ops = redisTemplate.opsForValue();
        String threadName = Thread.currentThread().getName();
        long startTime = System.currentTimeMillis();
        while (true) {
            if (Boolean.FALSE.equals(ops.getOperations().hasKey(id))) {
                ops.set(id, threadName, 10, TimeUnit.SECONDS);
                if (threadName.equals(ops.get(id))) {
                    // 加锁成功了,退出
                    log.info(threadName + "加锁成功");
                    break;
                }
            }
            if (System.currentTimeMillis() - startTime > 15 * 1000) {
                return "购买超时,请稍后重试";
            }
        }
        // 设置守护线程,防止还线程还没做完就key就过期了
        Thread daemonThread = ThreadUtils.getDaemon(() -> {
            while (true) {
                try {
                    Thread.sleep(9000);
                    ops.set(id, threadName, 10, TimeUnit.SECONDS);
                } catch (InterruptedException e) {
                    break;
                }
            }
        });
        try {
            // 说明没库存了
            if (goodsCount < 0 && goodsCount + goods.getStockNum() < 0) {
                return "库存不足!";
            }
            // 注意不能直接更新值
            log.info(String.valueOf(goodsMapper.updateGoodsStockNum(
            	goods.getGoodsId(), goodsCount, LocalDateTime.now())));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            daemonThread.interrupt();
            if (Objects.equals(ops.get(id), threadName)) {
                redisTemplate.delete(id);
                log.info(threadName + "释放锁");
            }
        }
        return ResultGenerator.ResultMsg.SUCCESS;
    }