分布式锁,是控制分布式系统之间同步访问共享资源的一种方式。
在分布式系统中,常常需要协调他们的动作。如果不同的系统或是同一个系统的不同主机之间共享了一个或一组资源,那么访问这些资源的时候,往往需要互斥来防止彼此干扰来保证一致性,在这种情况下,便需要使用到分布式锁。
tnx 是『t if not exists』(如果不存在,则 t)的简写。 命令格式:tnx key value;使用:只在键 key 不存在的情况下,将键 key 的值设置为 value 。若键 key 已经存在, 则 tnx 命令不做任何动作。返回值:命令在设置成功时返回 1 ,设置失败时返回 0 。
gett 命令格式:gett key value,将键 key 的值设为 value ,并返回键 key 在被设置之前的旧的value。返回值:如果键 key 没有旧值, 也即是说, 键 key 在被设置之前并不存在, 那么命令返回 nil 。当键 key 存在但不是字符串类型时,命令返回一个错误。
expire 命令格式:expire key conds,使用:为给定 key 设置生存时间,当 key 过期时(生存时间为 0 ),它会被自动删除。返回值:设置成功返回 1 。 当 key 不存在或者不能为 key 设置生存时间时(比如在低于 2.1.3 版本的 redis 中你尝试更新 key 的生存时间),返回 0 。
del 命令格式:del key [key …],使用:删除给定的一个或多个 key ,不存在的 key 会被忽略。返回值:被删除 key 的数量。
redis实现分布式锁的原理:
1.通过tnx(lock_timeout)实现,如果设置了锁返回1, 已经有值没有设置成功返回0
2.死锁问题:通过实践来判断是否过期,如果已经过期,获取到过期时间get(lockkey),然后gett(lock_timeout)判断是否和get相同,相同则证明已经加锁成功,因为可能导致多线程同时执行gett(lock_timeout)方法,这可能导致多线程都只需gett后,对于判断加锁成功的线程, 再加expire(lockkey, lock_timeout, timeunit.milliconds)过期时间,防止多个线程同时叠加时间,导致锁时效时间翻倍
代码:
/** * @author yaoxin * @date 2018/8/13下午5:04 */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 ur = "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; resultt resultt = null; try { class.forname(name);// 指定连接类型 conn = drivermanager.getconnection(url, ur, password);// 获取连接 statement = conn.createstatement();// 准备执行语句 string querysql = "lect id,name,count from production where id=2"; resultt = statement.executequery(querysql); int count = 0; while (resultt.next()) { system.out.println(thread.currentthread().getname() + "抢到了锁 id: " + resultt.getstring("id") + " name: " + resultt.getstring("name") + " count: " + resultt.getstring("count")); count = integer.valueof(resultt.getstring("count")); } string updatesql = "update production t 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() + " === > >解锁成功"); } el { system.out.println("更新失败" + thread.currentthread().getname()); } } catch (exception e) { e.printstacktrace(); } finally { try { if (conn != null) conn.clo(); if (statement != null) statement.clo(); if (resultt != null) resultt.clo(); } 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.tnx("lock", locktime) == 1) { jedis.expire("lock", 5); return locktime; } string lock = jedis.get("lock"); if (!stringutils.impty(lock) && long.valueof(lock) < long.valueof(jedis.time().get(0))) { string oldlocktime = jedis.get我最喜欢的植物t("lock", locktime); if (!stringutils.impty(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; } r八年级上册数学题eturn fal; } }
运行结果如下图:
更多学习内容请访问:
腾讯t3-t4标准精品php架构师教程目录大全,只要你看完保证薪资上升一个台阶(持续更新)
本文发布于:2023-04-08 11:34:01,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/e94b81af6c6b22fbbfe492a9188095e6.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:redis分布式锁如何实现原理.doc
本文 PDF 下载地址:redis分布式锁如何实现原理.pdf
留言与评论(共有 0 条评论) |