• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    redis锁机制介绍与实例

    1 悲观锁

    执行操作前假设当前的操作肯定(或有很大几率)会被打断(悲观)。基于这个假设,我们在做操作前就会把相关资源锁定,不允许自己执行期间有其他操作干扰。

    Redis不支持悲观锁。Redis作为缓存服务器使用时,以读操作为主,很少写操作,相应的操作被打断的几率较少。不采用悲观锁是为了防止降低性能。

    2 乐观锁

    执行操作前假设当前操作不会被打断(乐观)。基于这个假设,我们在做操作前不会锁定资源,万一发生了其他操作的干扰,那么本次操作将被放弃。

    3. Redis中的锁策略

    Redis采用了乐观锁策略(通过watch操作)。乐观锁支持读操作,适用于多读少写的情况!
    在事务中,可以通过watch命令来加锁;使用 UNWATCH可以取消加锁;
    如果在事务之前,执行了WATCH(加锁),那么执行EXEC 命令或 DISCARD 命令后,锁对自动释放,即不需要再执行 UNWATCH 了

    例子

    redis锁工具类

    package com.fly.lock;
    import redis.clients.jedis.Jedis;
    import redis.clients.jedis.JedisPool;
    import redis.clients.jedis.JedisPoolConfig;
    public class RedisLock {
      //初始化redis池
      private static JedisPoolConfig config;
      private static JedisPool pool;
      static {
        config = new JedisPoolConfig();
        config.setMaxTotal(30);
        config.setMaxIdle(10);
        pool = new JedisPool(config, "192.168.233.200", 6379);
      }
      /**
       * 给target上锁
       * @param target
       **/
      public static void lock(Object target) {
        //获取jedis
        Jedis jedis = pool.getResource();
        //result接收setnx的返回值,初始值为0
        Long result= 0L;
        while (result  1) {
          //如果target在redis中已经存在,则返回0;否则,在redis中设置target键值对,并返回1
          result = jedis.setnx(target.getClass().getName() + target.hashCode(), Thread.currentThread().getName());
        }
        jedis.close();
      }
      /**
       * 给target解锁
       * @param target
       **/
      public static void unLock(Object target) {
        Jedis jedis = pool.getResource();
        //删除redis中target对象的键值对
        Long del = jedis.del(target.getClass().getName() + target.hashCode());
        jedis.close();
      }
      /**
       * 尝试给target上锁,如果锁成功返回true,如果锁失败返回false
       * @param target
       * @return
       **/
      public static boolean tryLock(Object target) {
        Jedis jedis = pool.getResource();
        Long row = jedis.setnx(target.getClass().getName() + target.hashCode(), "true");
        jedis.close();
        if (row > 0) {
          return true;
        }
        return false;
      }
    }

    测试类

    package com.fly.test;
    import com.fly.lock.RedisLock;
    class Task {
      public void doTask() {
        //上锁
        RedisLock.lock(this);
        System.out.println("当前线程: " + Thread.currentThread().getName());
        System.out.println("开始执行: " + this.hashCode());
        try {
          System.out.println("doing...");
          Thread.sleep(2000);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        System.out.println("完成: " + this.hashCode());
        //解锁
        RedisLock.unLock(this);
      }
    }
    public class Demo {
      public static void main(String[] args) {
        Task task = new Task();
        Thread[] threads = new Thread[5];
        for (Thread thread : threads) {
          thread = new Thread(()->{
            task.doTask();
          });
          thread.start();
        }
      }
    }

    输出结果:

    ----------------------------------------------
    当前线程: Thread-0
    开始执行: 2081499965
    doing...
    完成: 2081499965
    ----------------------------------------------
    当前线程: Thread-2
    开始执行: 2081499965
    doing...
    完成: 2081499965
    ----------------------------------------------
    当前线程: Thread-1
    开始执行: 2081499965
    doing...
    完成: 2081499965
    ----------------------------------------------
    当前线程: Thread-4
    开始执行: 2081499965
    doing...
    完成: 2081499965
    ----------------------------------------------
    当前线程: Thread-3
    开始执行: 2081499965
    doing...
    完成: 2081499965

    去掉redis锁后,执行结果:

    ----------------------------------------------
    ----------------------------------------------
    当前线程: Thread-2
    开始执行: 1926683415
    ----------------------------------------------
    当前线程: Thread-1
    doing...
    当前线程: Thread-0
    ----------------------------------------------
    当前线程: Thread-3
    开始执行: 1926683415
    doing...
    开始执行: 1926683415
    doing...
    ----------------------------------------------
    开始执行: 1926683415
    doing...
    当前线程: Thread-4
    开始执行: 1926683415
    doing...
    完成: 1926683415
    完成: 1926683415
    完成: 1926683415
    完成: 1926683415
    完成: 1926683415

    Process finished with exit code 0

    利用redis这个性质,可以实现分布式锁,当然设计一定复杂一些!

    总结

    以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。如果你想了解更多相关内容请查看下面相关链接

    您可能感兴趣的文章:
    • CentoS6.5环境下redis4.0.1(stable)安装和主从复制配置方法
    • Redis教程(九):主从复制配置实例
    • Redis主从复制问题和扩容问题的解决思路
    • gem install redis报错的解决方案
    • 使用Ruby脚本部署Redis Cluster集群步骤讲解
    • Redis Cluster的图文讲解
    • Redis cluster集群的介绍
    • redis持久化的介绍
    • SpringBoot AOP控制Redis自动缓存和更新的示例
    • Redis主从复制详解
    上一篇:大家都应该知道的Redis过期键与过期策略
    下一篇:redis持久化的介绍
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    redis锁机制介绍与实例 redis,锁,机制,介绍,与,实例,