当前位置: 首页 > wzjs >正文

手机网站制作代码福田做商城网站建设哪家技术好

手机网站制作代码,福田做商城网站建设哪家技术好,宁波网站推广厂家,上海城隍庙引言 在本篇中,我们继续探索redisson中相关锁的实现,本期将围绕公平锁进行讲解。在正式开始前,我们回顾下公平锁的概念-在多线程或分布式环境中,锁的获取是有先后顺序的,按照请求顺序来获得锁。这就意味着A、B、C 三个…

引言

在本篇中,我们继续探索redisson中相关锁的实现,本期将围绕公平锁进行讲解。在正式开始前,我们回顾下公平锁的概念-在多线程或分布式环境中,锁的获取是有先后顺序的,按照请求顺序来获得锁。这就意味着A、B、C 三个线程都想获得同一把锁,那么最先请求的线程会被优先给予资源。如果此时锁被某个线程占用,其余线程会根据各自的排队顺序来抢占锁,谁排在前面,谁就先获得锁。

在 Redisson 中,对分布式 Redis 锁的公平性,就是说锁的获取需要按照先来后到排队,避免后来的请求“插队”。

加锁

我们先来看看如何实现加锁的,在 RedissonFairLock 类里,我们可以找到核心加锁逻辑:

public void lock() {try {// 1. 尝试获取锁if (tryAcquire()) {return;}// 2. 获取失败,将当前线程信息写入等待队列long threadId = Thread.currentThread().getId();Long ttl = tryAcquisition(threadId);// 3. 循环等待获取锁while (ttl != null) {// 订阅锁释放消息subscribe(threadId);// 等待锁释放通知await(ttl);// 重试获取锁ttl = tryAcquisition(threadId);}} finally {// 取消订阅unsubscribe(Thread.currentThread().getId());}
}

可以看到调用tryAcquisition方法来尝试获取锁,这个方法里则封装了相关的Lua脚本,如下:

private Long tryAcquisition(long threadId) {return redis.eval("""-- 检查锁是否已被占用if (redis.call('exists', KEYS[1]) == 0) then-- 获取锁并设置threadIdredis.call('hset', KEYS[1], ARGV[2], 1);redis.call('pexpire', KEYS[1], ARGV[1]);-- 将线程加入等待队列末尾redis.call('zadd', KEYS[2], ARGV[3], ARGV[2]);return nil;end;-- 检查是否是队列第一个等待者local firstThreadId = redis.call('zrange', KEYS[2], 0, 0);if (firstThreadId[1] == ARGV[2]) then-- 获取锁redis.call('hset', KEYS[1], ARGV[2], 1);redis.call('pexpire', KEYS[1], ARGV[1]);-- 从等待队列移除redis.call('zrem', KEYS[2], ARGV[2]);return nil;end;-- 返回需要等待的时间return redis.call('pttl', KEYS[1]);""");

在尝试获取锁时:首先尝试直接获取锁;如果获取失败,将线程信息加入等待队列;只有当前线程是等待队列的第一个时才能获取锁;获取失败则订阅锁释放消息并等待;等待后重试获取锁,直到成功。

释放锁

看完了加锁,我们继续看释放锁,释放锁的核心逻辑在于Lua脚本的实现:

public void unlock() {redis.eval("""-- 检查是否是锁持有者if (redis.call('hexists', KEYS[1], ARGV[2]) == 0) thenreturn nil;end;-- 减少重入计数local counter = redis.call('hincrby', KEYS[1], ARGV[2], -1);if (counter > 0) thenredis.call('pexpire', KEYS[1], ARGV[1]);return 0;end;-- 删除锁redis.call('del', KEYS[1]);-- 发布释放消息redis.call('publish', KEYS[2], ARGV[2]);return 1;""");

解锁过程:验证当前线程是否是锁的持有者;处理重入计数的递减;当计数为0时完全释放锁;发布锁释放消息通知等待线程。

为何能保障“公平”?

1.先排队

Redisson 在请求 lock 时,会先把线程标识以一定的 score(通常是时间戳)存储进 ZSet。这样就等于“先到先排队”。

2.只允许队首“抢”锁

脚本会检查 ZSet 的首位元素(ZRANGE KEYS[2], 0, 0),只有首位(rank == 0)的线程才有真正“尝试加锁”的资格。

3.不可插队

因为 Lua 脚本在 Redis 里是原子执行的,不会出现其他线程“并发修改队列”的情况,且 ZSet 的 score 是根据时间先后确定顺序。不会让后来的线程“插队”。

4.线程之间实时通知

当锁释放后,publish 通知所有订阅方,后面排队的线程就能及时知道“锁可以重新争抢了”,然后再调用加锁脚本进行排名检查,最终实现“先来先拿”。

小结

通过这些 Lua 脚本的实现逻辑,相信各位读者已经理解了 Redisson 公平锁为什么能做到“先来先得”,以及其在分布式环境下是如何保证线程安全、互不干扰的。还是那句话,看源码的目的在于学习别人优秀的设计,希望对大家有所启发!


文章转载自:

http://q4LiHKs3.wsrcy.cn
http://3HcsGLy2.wsrcy.cn
http://Cr54LeQC.wsrcy.cn
http://6GfixEpe.wsrcy.cn
http://YN0JboUY.wsrcy.cn
http://OYgU0wO7.wsrcy.cn
http://MaQaRBOS.wsrcy.cn
http://CsdqtIXm.wsrcy.cn
http://cyOG1zEN.wsrcy.cn
http://e00rERkD.wsrcy.cn
http://IY4H90GM.wsrcy.cn
http://1TgAjROL.wsrcy.cn
http://vLlp73yo.wsrcy.cn
http://FUhkrcw0.wsrcy.cn
http://6juaC2J7.wsrcy.cn
http://tnIDIsOS.wsrcy.cn
http://zF1LTBXN.wsrcy.cn
http://SuDJuuzN.wsrcy.cn
http://AZGJiOzs.wsrcy.cn
http://Jx5P6sGE.wsrcy.cn
http://mlzwtcKE.wsrcy.cn
http://UbHj9siR.wsrcy.cn
http://Eo6CjU0r.wsrcy.cn
http://E5gi9RO3.wsrcy.cn
http://nuvMViWA.wsrcy.cn
http://z50abJJw.wsrcy.cn
http://KX7EfAnf.wsrcy.cn
http://Fd1nZQfd.wsrcy.cn
http://Rj7A9Yfy.wsrcy.cn
http://h36WRe64.wsrcy.cn
http://www.dtcms.com/wzjs/612118.html

相关文章:

  • 备案不关闭网站怎么样用vps建网站备案
  • 横向网站如何删除wordpress模板底部的签名
  • 江门专用网站建设南昌有哪些企业网站
  • 职业院校专题建设网站wordpress卖东西
  • 如何用手机创建网站wordpress sae 安装主题
  • 目前网站建设用哪种语言wordpress 500 php版本
  • 广州天河网站制作wordpress电商优秀
  • 投票网站定制网站开发需要多少钱新闻
  • 联通企业网站建设百度会员
  • 网站开发实施方案网络营销与线上营销的区别
  • 绍兴专门做网站的公司时尚网站网页设计
  • 阿里云手机版网站建设深圳vi设计公司哪家专业
  • 网站的意思网页设计与制作教程第2版
  • 简单建站的网站网站建设系统服务机构
  • 网站页脚有什么作用北京最大的商场
  • 青岛网站制作选ls15227做海报设计的网站
  • 软件开发前端做抖音seo用哪些软件
  • 天津网站排名中国建设银行官网站金银纪念币
  • 衡水网站建设怎么做如何确定网站建设 栏目
  • 常见门户网站的基本功能国内做任务得数字货币的网站
  • 一般网站的宽度烟台艺术学校官网
  • 网站页面关键词优化同一源代码再建设一个网站
  • 游戏推广网站如何做的怎么买网站
  • 个人建设网站还要备案么自己制作简易网页
  • 建设企业网站优势wordpress媒体库删除
  • 学做网站什么语言合适江苏网站推广公司
  • 免费虚拟空间网站淘宝网站建设原理
  • 用scala做的网站做网站的图片传进去很模糊
  • 技术支持 骏域网站建设专家佛山杭州网站建设及推广
  • 网站链接查询深圳动力网站设计公司