redis实现分布式锁

Posted 炫舞风中

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了redis实现分布式锁相关的知识,希望对你有一定的参考价值。

1、maven

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
       <version>2.2.2.RELEASE</version>
</dependency>

2、代码

 @GetMapping("redis")
    public String redis(){
        final String lock = "locked";
        String uuid = UUID.randomUUID().toString();
        Boolean locked = stringRedisTemplate.opsForValue().setIfAbsent(lock, uuid, 30, TimeUnit.SECONDS);
        if (!locked){
           return "没有拿到锁";
        }
        ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1,
                new BasicThreadFactory.Builder().namingPattern("locked-schedule-pool-%d").daemon(false).build());
        executorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                //开启定时器线程为指定的key延长,防止主线程的操作还未执行完,lock已经因为过期而删除
                stringRedisTemplate.expire(lock,30, TimeUnit.SECONDS);
            }
            //执行周期一般为设置的过期时间的1/3
        },10,10, TimeUnit.SECONDS);
        try {
            Integer product = Integer.parseInt(stringRedisTemplate.opsForValue().get("product"));
            if (product>0){
                product = product-1;
                System.out.println("继续出售="+product);
                stringRedisTemplate.opsForValue().set("product",product.toString());
            }else{
                System.out.println("卖完了");
            }
        }finally {
            //执行完毕,释放定时器
            executorService.shutdown();
            //只能删除自己的锁
            DefaultRedisScript defaultRedisScript = new DefaultRedisScript();
            //执行lua脚本 保证原子性 (主要是防止判断的时候满足条件,在删除的时刻,刚好过期,导致删除其他线程设置的锁)
            defaultRedisScript.setScriptText("if redis.call(‘get‘,KEYS[1]) == ARGV[1] then redis.call(‘del‘,KEYS[1]) end");
            List<String> keys = new ArrayList<>();
            keys.add(lock);
             stringRedisTemplate.execute(defaultRedisScript, keys, uuid);
        }
      return "ok";
    }

以上是关于redis实现分布式锁的主要内容,如果未能解决你的问题,请参考以下文章

分布式锁三种解决方案

分布式锁Redis分布式锁注解灵活实现

分布式锁,及Redis实现分布式锁

80% 人不知道的 Redis 分布式锁的正确实现方式(Java 版)

Redis 分布式锁的作用及实现(序列四)

redis基于redis实现分布式并发锁