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

如今做哪些网站能致富wordpress小工具下载

如今做哪些网站能致富,wordpress小工具下载,免费推广的渠道有哪些,搜索引擎哪个好上一篇文章提到使用针对不同的业务场景如何合理使用Redis分布式锁#xff0c;并引入了一个新的问题 若定义锁的过期时间是10s#xff0c;此时A线程获取了锁然后执行业务代码#xff0c;但是业务代码消耗时间花费了15s。这就会导致A线程还没有执行完业务代码#xff0c;A线程… 上一篇文章提到使用针对不同的业务场景如何合理使用Redis分布式锁并引入了一个新的问题 若定义锁的过期时间是10s此时A线程获取了锁然后执行业务代码但是业务代码消耗时间花费了15s。这就会导致A线程还没有执行完业务代码A线程却释放了锁因为10s到了第11s B线程发现锁已经释放重新获取锁也开始执行业务代码。 此时多个线程同时执行业务代码我们使用锁就是为了保证仅有一个线程执行这一块业务代码说明这个锁是失效的 本文将尝试探讨如何处理这个问题 下面这个图解释了重置超时时间是什么意思写一个定时任务并单独使用一个线程每3s去检查一下是否到终点任务是否执行完毕第3s时发现没到终点重置时间。 假设任务执行完毕需要花费11s。那么锁一共会延期3次第11s之后锁被手动释放如果没释放。等到第19s时会被自动释放。 如何实现锁的延期 伪代码定义锁的结构 keyuuid value订单服务if key锁的唯一标识是否存在存在if 锁是否被修改未修改重置超时时间这部分有一点需要解释 为什么判断锁是否被修改 A线程获取了锁之后B线程修改锁的value为 “文件下载服务”不加一层校验A线程就会对修改后的锁操作而不是原始的锁。 此时你会直接写一个定时任务去实现会有什么问题吗 锁延期分为2步第一步判断锁第二步重置锁这2步之间是存在间隙的完全可以在判断锁后重置锁前发生一些事情例如恰巧在重置时间前锁被其他线程修改了。如何才能避免这个间隙不发生意外 使用lua脚本使用lua语法实现锁的延期然后执行这个脚本。lua语法将这两个步骤绑定成一个操作。这也就是为什么提到锁延期的实现基本都是采用lua实现的根本原因。redis分布式锁自身是有局限性的不能满足我们的需求所以我们提出了锁延期。 巧在Redis很支持lua语法我们只需要按照lua语法要求写好命令调用Redis提供的方法入口传进去Redis会自动解析这些命令。更巧在lua语法实现锁延期解决了上面的隐患。。。 /*** 锁续期*/if (redis.call(exists, KEYS[1]) 1) then // 锁还存在if (redis.call(get, KEYS[1]) ARGV[1]) then redis.call(pexpire, KEYS[1], ARGV[2]) );// 重置超时时间return 1endendreturn 0接下来完整的看一下如何使用Redis锁延期 /*** redis分布式锁* 为了文件拉取加的可能存在拉取任务耗时很久的情况增加锁延时操作* author lixinyu*/ public class RedisDistributeLock {private static final Logger log LoggerFactory.getLogger(RedisDistributeLock.class);// 默认30秒后自动释放锁private static long defaultExpireTime 10 * 60 * 1000; // 默认10分钟// 用于锁延时任务的执行private static ScheduledThreadPoolExecutor renewExpirationExecutor;// 加锁和解锁的lua脚本 重入和不可重入两种private static String lockScript;private static String unlockScript;private static String renewScript;// 锁延时脚本private static String lockScript_reentrant;private static String unlockScript_reentrant;private static String renewScript_reentrant;// 锁延时脚本static {/*** 如果指定的锁键(KEYS[1])不存在则通过set命令设置锁的值(ARGV[1])和超时时间(ARGV[2])。* 如果锁键已存在则通过pttl命令返回锁的剩余超时时间。*/StringBuilder sb new StringBuilder();sb.setLength(0);sb.append( if (redis.call(exists, KEYS[1]) 0) then );// 如果不存在这个lockKey锁sb.append( redis.call(set, KEYS[1], ARGV[1]) );// 设置锁 key-value结构sb.append( redis.call(pexpire, KEYS[1], ARGV[2]) );// 设置锁超时时间sb.append( return nil );sb.append( end );sb.append( return redis.call(pttl, KEYS[1]) );// 如果别的线程已经加锁返回剩余时间lockScript sb.toString();/*** 如果锁存在则删除锁*/sb.setLength(0);sb.append( if (redis.call(get, KEYS[1]) ARGV[1]) then );sb.append( return redis.call(del, KEYS[1]) );sb.append( else return 0 );sb.append( end);unlockScript sb.toString();/*** 可重入锁主要解决的是同一个线程能够多次获取锁的问题而不是防止多个线程同时获取锁* 这通常发生在方法递归调用、嵌套调用或者同一个方法内部多次执行加锁操作的情况下*/sb.setLength(0);sb.append( if (redis.call(exists, KEYS[1]) 0) then );// 如果不存在这个lockKey锁sb.append( redis.call(hset, KEYS[1], ARGV[1], 1) );// 设置锁 hash结构hashkey为当前线程id加锁数为1sb.append( redis.call(pexpire, KEYS[1], ARGV[2]) );// 设置锁超时时间sb.append( return nil );sb.append( end );sb.append( if (redis.call(hexists, KEYS[1], ARGV[1]) 1) then );// 如果当前线程已经加锁sb.append( redis.call(hincrby, KEYS[1], ARGV[1], 1) );// 可重入增加锁计数sb.append( redis.call(pexpire, KEYS[1], ARGV[2]) );// 重设置锁超时时间sb.append( return nil );sb.append( end );sb.append( return redis.call(pttl, KEYS[1]) );// 如果别的线程已经加锁返回剩余时间lockScript_reentrant sb.toString();/*** 释放锁通过判断锁的存在、当前线程是否是加锁的线程、以及锁的计数器等条件来实现解锁的操作*/sb.setLength(0);sb.append( if (redis.call(exists, KEYS[1]) 0) then );// 不存在锁返回1表示解锁成功sb.append( return 1 );sb.append( end );sb.append( if (redis.call(hexists, KEYS[1], ARGV[1]) 0) then );// 存在锁不是本人加的返回0失败sb.append( return 0 );sb.append( end );sb.append( local counter redis.call(hincrby, KEYS[1], ARGV[1], -1) );// 存在自己加的锁锁计数减一sb.append( if (counter 0) then );// 判断是否要删除锁或重置超时时间sb.append( redis.call(pexpire, KEYS[1], ARGV[2]) );sb.append( return 0 );sb.append( else );sb.append( redis.call(del, KEYS[1]) );sb.append( return 1 );sb.append( end );sb.append( return nil );unlockScript_reentrant sb.toString();/*** 锁续期*/sb.setLength(0);sb.append( if (redis.call(exists, KEYS[1]) 1) then );// 锁还存在sb.append( if (redis.call(get, KEYS[1]) ARGV[1]) then );sb.append( redis.call(pexpire, KEYS[1], ARGV[2]) );// 重置超时时间sb.append( return 1);sb.append( end );sb.append( end );sb.append( return 0 );renewScript sb.toString();/*** 可重入锁续期*/sb.setLength(0);sb.append( if (redis.call(hexists, KEYS[1], ARGV[1]) 1) then );// 锁还存在sb.append( redis.call(pexpire, KEYS[1], ARGV[2]) );// 重置超时时间sb.append( return 1 );sb.append( end );sb.append( return 0 );renewScript_reentrant sb.toString();renewExpirationExecutor new ScheduledThreadPoolExecutor(2);}private String uuid;// 当前锁对象标识private boolean reentrant;// 当前锁是可重入还是不可重入private RedisUtils redisUtils;public RedisDistributeLock(boolean reentrant) {this.uuid UUIDUtils.randomUUID8();this.reentrant reentrant;this.redisUtils SpringApplicationUtils.getBean(RedisUtils.class);}/*** 尝试对lockKey加锁* author: lixinyu 2023/4/25**/public boolean tryLock(String lockKey) {String script lockScript;if (reentrant) {script lockScript_reentrant;}Object result redisUtils.evalScript(script, ReturnType.INTEGER, 1, lockKey, uuid, String.valueOf(defaultExpireTime));boolean isSuccess result null;if (isSuccess) {// 若成功增加延时任务scheduleExpirationRenew(lockKey, uuid, reentrant);}return isSuccess;}/*** 解锁* author: lixinyu 2023/4/25**/public void unlock(String lockKey){if (reentrant) {redisUtils.evalScript(unlockScript_reentrant, ReturnType.INTEGER, 1, lockKey, uuid, String.valueOf(defaultExpireTime));} else {redisUtils.evalScript(unlockScript, ReturnType.INTEGER, 1, lockKey, uuid);}}/*** 锁延时定时任务队列定时判断一次是否续期*/private void scheduleExpirationRenew(String lockKey, String lockValue, boolean reentrant) {Runnable renewTask new Runnable(){Overridepublic void run() {try {String script renewScript;if (reentrant) {script renewScript_reentrant;}// 将lua语法传给redis解析Object result evalScript(script, ReturnType.INTEGER, 1, lockKey, lockValue, String.valueOf(defaultExpireTime));if (result ! null !result.equals(false) result.equals(Long.valueOf(1))) {// 延时成功再定时执行scheduleExpirationRenew(lockKey, lockValue, reentrant);log.info(redis锁【 lockKey 】延时成功);}} catch (Exception e) {log.error(scheduleExpirationRenew run异常, e);}}};renewExpirationExecutor.schedule(renewTask, defaultExpireTime / 3, TimeUnit.MILLISECONDS);} } /*** 将lua语法传给redis*/ public Object evalScript(String script, ReturnType returnType, int numKeys,String... keysAndArgs){Object value false;try{value redisTemplate.execute((RedisCallbackObject)conn - {try{byte[][] keysAndArgsByte new byte[keysAndArgs.length][];for (int i 0; i keysAndArgs.length; i ){keysAndArgsByte[i] redisTemplate.getStringSerializer().serialize(keysAndArgs[i]);}return conn.eval(redisTemplate.getStringSerializer().serialize(script), returnType, numKeys,keysAndArgsByte);}catch (SerializationException e){log.error(异常, e);return false;}});}catch (Exception e){log.error(异常, e);}return value;}使用锁 private void demo() {RedisDistributeLock lock new RedisDistributeLock(false);String lockKey redisSeqPrefix lock: seqName;try {if (lock.tryLock(lockKey)) {String redisValue redisUtils.get(redisSeqPrefix seqName);// 加锁之后再次判断是否超出规定长度防止并发时重置多次if (redisValue ! null redisValue.length() seqLength) {redisUtils.set(redisSeqPrefix seqName, 1);}}} catch (Exception e) {logger.error(resetSeqValue异常, e);} finally {lock.unlock(lockKey);}}不仅仅是锁延期需要两步判断锁是否存在、重置时间删除锁也需要两步判断锁是否存在、删除锁这也需要保证原子性所以建议使用lua脚本实现。 你干脆想到要不然我获取锁、解锁、获取可重入锁、解可重入锁锁延期等等都写成lua脚本吧但是工作量好像就变多了。 Redisson 提供了高级的分布式对象和服务使用起来非常简单不需要手动编写复杂的 Lua 脚本。只需要引入Redisson 的依赖库 Redisson 提供了许多高级功能如分布式集合、分布式锁、分布式队列等。这些功能是为了解决常见的分布式应用场景而设计的使用 Redisson 可以更轻松地集成这些功能 如果你只是一些简单的功能可以自定义lua脚本实现毕竟引入新的依赖库就需要维护这个库看怎么考虑了。
http://www.pierceye.com/news/249939/

相关文章:

  • 电商网站建设代理商定制网站开发介绍图
  • 网站系统问题解决措施上海网站建设系
  • c 做网站简单吗ui设计需要学什么软件
  • 网站建设app开发公司国内免备案空间
  • nas 支持做网站dedecms 做影网站
  • 网上商城网站模板广州建设技术职业学院
  • 养生网站模板下载山东网站建设哪家专业
  • 最新电子产品网站模板网站建设公司 腾佳
  • 跟公司产品做网站用什么程序做网站最好优化
  • 在线代理网页浏览网站山东省城乡住房建设厅网站
  • 网站建设需准备什么彩页模板图片
  • 怎么用网站源码建站网站换空间步骤
  • 酒店网站开发回扣商丘企业网站建设服务
  • 网站建设策划解决方案河北自助建站系统平台
  • 有没有做高仿手表的网站设计师的职责
  • struts2 做的网站seo公司怎样找客户
  • 帮别人做网站赚钱吗中山快速建站合作
  • 保靖网站建设做网站要运用到代码吗
  • 我用织梦5.7做个网站应该把淘宝客店铺链接放到哪frontpage可以制作网页吗
  • 潍坊优化网站排名在线网页设计培训机构
  • c做的网站ps做 网站标准尺寸
  • 老虎淘客系统可以做网站吗wordpress po mo
  • 网站的建设与维护那个网站做图片好
  • 昆山网站建设详细方案建设企业网站初始必备的六大功能
  • 做网站是前端还是后端网站规划 设计 制作 发布与管理过程
  • 黄山网站开发威县做网站哪里便宜
  • 网站怎么分类视频聚合网站怎么做不侵权
  • 有没有做问卷还能赚钱的网站套别人的网站模板吗
  • 东莞做汽车有没有买票的网站做谷歌推广一个月赚10万
  • 抚州城乡建设厅网站建设局官网查询