zoukankan      html  css  js  c++  java
  • 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";
        }
  • 相关阅读:
    vue token使用 参考
    token 的作用与使用
    jq 绑定实时监听 input输入框
    认识java
    java基础语法
    java虚拟机笔记 运行时内存区域划分
    spring全家桶
    利用python脚本统计和删除redis key
    MySQL中count(字段) ,count(主键 id) ,count(1)和count(*)的区别
    编写shell脚本的一些规范
  • 原文地址:https://www.cnblogs.com/cq-yangzhou/p/12215035.html
Copyright © 2011-2022 走看看