我的编程空间,编程开发者的网络收藏夹
学习永远不晚

redis实现分布式锁的原理是什么

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

redis实现分布式锁的原理是什么

这期内容当中小编将会给大家带来有关redis实现分布式锁的原理,以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

分布式锁,是控制分布式系统之间同步访问共享资源的一种方式。

在分布式系统中,常常需要协调他们的动作。如果不同的系统或是同一个系统的不同主机之间共享了一个或一组资源,那么访问这些资源的时候,往往需要互斥来防止彼此干扰来保证一致性,在这种情况下,便需要使用到分布式锁。

使用setnx、getset、expire、del这4个redis命令实现  

setnx 是『SET if Not eXists』(如果不存在,则 SET)的简写。 命令格式:SETNX key value;使用:只在键 key 不存在的情况下,将键 key 的值设置为 value 。若键 key 已经存在, 则 SETNX 命令不做任何动作。返回值:命令在设置成功时返回 1 ,设置失败时返回 0 。

getset 命令格式:GETSET key value,将键 key 的值设为 value ,并返回键 key 在被设置之前的旧的value。返回值:如果键 key 没有旧值, 也即是说, 键 key 在被设置之前并不存在, 那么命令返回 nil 。当键 key 存在但不是字符串类型时,命令返回一个错误。

expire 命令格式:EXPIRE key seconds,使用:为给定 key 设置生存时间,当 key 过期时(生存时间为 0 ),它会被自动删除。返回值:设置成功返回 1 。 当 key 不存在或者不能为 key 设置生存时间时(比如在低于 2.1.3 版本的 Redis 中你尝试更新 key 的生存时间),返回 0 。

del 命令格式:DEL key [key …],使用:删除给定的一个或多个 key ,不存在的 key 会被忽略。返回值:被删除 key 的数量。

Redis实现分布式锁的原理:

1.通过setnx(lock_timeout)实现,如果设置了锁返回1, 已经有值没有设置成功返回0

2.死锁问题:通过实践来判断是否过期,如果已经过期,获取到过期时间get(lockKey),然后getset(lock_timeout)判断是否和get相同,相同则证明已经加锁成功,因为可能导致多线程同时执行getset(lock_timeout)方法,这可能导致多线程都只需getset后,对于判断加锁成功的线程, 再加expire(lockKey, LOCK_TIMEOUT, TimeUnit.MILLISECONDS)过期时间,防止多个线程同时叠加时间,导致锁时效时间翻倍

redis实现分布式锁的原理是什么代码:


public class RedisLockTest {
 
    public static final String url = "jdbc:mysql://127.0.0.1:3306/ly?characterEncoding=UTF-8";
    public static final String name = "com.mysql.jdbc.Driver";
    public static final String user = "root";
    public static final String password = "";
 
    public static void main(String[] args) {
 
        Integer count = 50;
        while (count > 0) {
            count--;
            new Thread(new Runnable() {
                @Override
                public void run() {
                    Jedis jedis = new Jedis("127.0.0.1", 6379);
                    jedis.auth("1234");
                    String lock = lock(jedis);
                    if (lock != null) {
                        Statement statement = null;
                        Connection conn = null;
                        ResultSet resultSet = null;
                        try {
                            Class.forName(name);// 指定连接类型
                            conn = DriverManager.getConnection(url, user, password);// 获取连接
                            statement = conn.createStatement();// 准备执行语句
                            String querySql = "SELECT id,name,count FROM production WHERE id=2";
                            resultSet = statement.executeQuery(querySql);
                            int count = 0;
                            while (resultSet.next()) {
                                System.out.println(Thread.currentThread().getName() + "抢到了锁 id: " + resultSet.getString("id")
                                        + " name: " + resultSet.getString("name")
                                        + " count: " + resultSet.getString("count"));
                                count = Integer.valueOf(resultSet.getString("count"));
                            }
                            String updateSql = "UPDATE production SET count=" + (count - 1)
                                    + " WHERE id=2";
                            int rows = statement.executeUpdate(updateSql);
                            if (rows > 0) {
                                System.out.println("更新成功" + Thread.currentThread().getName() + "  库存剩余:" + (count - 1));
                                System.out.println(Thread.currentThread().getName() + " === > >开始解锁");
                                boolean unlock = unlock(jedis, lock);
                                if (unlock)
                                    System.out.println(Thread.currentThread().getName() + " === > >解锁成功");
                            } else {
                                System.out.println("更新失败" + Thread.currentThread().getName());
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        } finally {
                            try {
                                if (conn != null)
                                    conn.close();
                                if (statement != null)
                                    statement.close();
                                if (resultSet != null)
                                    resultSet.close();
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }, "线程" + count).start();
        }
    }
 
    public static String lock(Jedis jedis) {
        try {
            while (true) {
                String lockTime = Long.valueOf(jedis.time().get(0)) + 5 + "";
                if (jedis.setnx("lock", lockTime) == 1) {
                    jedis.expire("lock", 5);
                    return lockTime;
                }
                String lock = jedis.get("lock");
                if (!StringUtils.isEmpty(lock) && Long.valueOf(lock) < Long.valueOf(jedis.time().get(0))) {
                    String oldLockTime = jedis.getSet("lock", lockTime);
                    if (!StringUtils.isEmpty(oldLockTime) && oldLockTime.equals(lock)) {
                        return lockTime;
                    }
                }
                Thread.sleep(100);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
 
    public static boolean unlock(Jedis jedis, String lockTag) {
        if (lockTag.equals(jedis.get("lock"))) {
            jedis.del("lock");
            return true;
        }
        return false;
    }
 
}

运行结果如下图:

redis实现分布式锁的原理是什么

上述就是小编为大家分享的redis实现分布式锁的原理,如果您也有类似的疑惑,不妨参照上述方法进行尝试。如果想了解更多相关内容,请关注亿速云行业资讯。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

redis实现分布式锁的原理是什么

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Redis分布式锁的原理是什么和怎么实现

这篇文章主要介绍了Redis分布式锁的原理是什么和怎么实现的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Redis分布式锁的原理是什么和怎么实现文章都会有所收获,下面我们一起来看看吧。1 一人一单并发安全问题之
2023-07-04

分布式锁的原理及Redis怎么实现分布式锁

这篇文章主要介绍“分布式锁的原理及Redis怎么实现分布式锁”,在日常操作中,相信很多人在分布式锁的原理及Redis怎么实现分布式锁问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”分布式锁的原理及Redis怎么
2023-02-02

Redis分布式锁的实现原理介绍

这篇文章主要讲解了“Redis分布式锁的实现原理介绍”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Redis分布式锁的实现原理介绍”吧!一、写在前面现在面试,一般都会聊聊分布式系统这块的东西
2023-06-02

分布式锁redis实现方式是什么

分布式锁的Redis实现方式有两种:基于SETNX命令和基于RedLock算法。1. 基于SETNX命令:使用Redis的SETNX命令来实现分布式锁。该命令用于设置一个键的值,但只有在该键不存在时才会设置成功。通过使用SETNX命令,可以
2023-09-12

redis分布式锁的实现原理实例分析

这篇文章主要介绍了redis分布式锁的实现原理实例分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇redis分布式锁的实现原理实例分析文章都会有所收获,下面我们一起来看看吧。首先,为了确保分布式锁可用,我们至
2023-06-29

Spring Boot 实现Redis分布式锁原理

这篇文章主要介绍了Spring Boot实现Redis分布式锁原理,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的朋友可以参考一下
2022-11-13

InterProcessMutex实现zookeeper分布式锁原理是什么

这篇“InterProcessMutex实现zookeeper分布式锁原理是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇
2023-06-29

详解Redis分布式锁的原理与实现

目录前言使用场景为什么要使用分布式锁如何使用分布式锁流程图分布式锁的状态分布式锁的特点分布式锁的实现方式(以redis分布式锁实现为例)总结前言在单体应用中,如果我们对共享数据不进行加锁操作,会出现数据一致性问题,我们的解决办法通常是加锁
2022-06-23

Redis分布式锁实现的方法是什么

本篇内容主要讲解“Redis分布式锁实现的方法是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Redis分布式锁实现的方法是什么”吧!一、分布式锁是什么分布式锁是 满足分布式系统或集群模式下
2023-07-05

Redis实现分布式锁

单体锁存在的问题 在单体应用中,如果我们对共享数据不进行加锁操作,多线程操作共享数据时会出现数据一致性问题。 (下述实例是一个简单的下单问题:从redis中获取库存,检查库存是否够,>0才允许下单) 我们的解决办法通常是加锁。如下加单体锁
2023-08-16

编程热搜

目录