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

建筑工程公司有哪些最好的优化公司排名

建筑工程公司有哪些,最好的优化公司排名,wordpress wow.js,餐饮wordpress模板一、使用Redisson步骤 Redisson各个锁基本所用Redisson各个锁基本所用Redisson各个锁基本所用 二、源码解析 lock锁 1#xff09; 基本思想#xff1a; lock有两种方法 一种是空参 另一种是带参 * 空参方法#xff1a;会默认调用看门狗的过期时间30*1000…一、使用Redisson步骤 Redisson各个锁基本所用Redisson各个锁基本所用Redisson各个锁基本所用 二、源码解析 lock锁 1 基本思想 lock有两种方法 一种是空参  另一种是带参          * 空参方法会默认调用看门狗的过期时间30*100030秒          * 然后在正常运行的时候会启用定时任务调用重置时间的方法间隔为开门看配置的默认过期时间的三分之一也就是10秒          * 当出现错误的时候就会停止续期直到到期释放锁或手动释放锁          * 带参方法手动设置解锁时间到期后自动解锁或者业务完成后手动解锁不会自动续期 源码 Lock 调用lockInterruptibly()方法会默认传入lease 为-1该值再后面起作用 public void lockInterruptibly(long leaseTime, TimeUnit unit) throws InterruptedException {long threadId Thread.currentThread().getId();//获取该锁的过期时间如果该锁没被持有会返回一个null如果被持有 会返回一个过期时间Long ttl this.tryAcquire(leaseTime, unit, threadId);if (ttl ! null) {//ttl不为null说明锁已经被抢占了RFutureRedissonLockEntry future this.subscribe(threadId);this.commandExecutor.syncSubscription(future);try {//开始循环获取锁while(true) {//刚进如循环先尝试获取锁获取成功返回null跳出循环获取失败则继续往下走ttl this.tryAcquire(leaseTime, unit, threadId);if (ttl null) {return;}if (ttl 0L) {//如果过期时间大于0则调用getLatch// 返回一个信号量开始进入阻塞阻塞时长为上一次锁的剩余过期时长并且让出cup//有阻塞必然有唤醒位于解锁操作中this.getEntry(threadId).getLatch().tryAcquire(ttl, TimeUnit.MILLISECONDS);} else {this.getEntry(threadId).getLatch().acquire();}}} finally {this.unsubscribe(future, threadId);}}} private T RFutureLong tryAcquireAsync(long leaseTime, TimeUnit unit, final long threadId) {//如果leaseTime -1即不等于默认值则表示手动设置了过期时间if (leaseTime ! -1L) {return this.tryLockInnerAsync(leaseTime, unit, threadId, RedisCommands.EVAL_LONG);} else {//如果leaseTime -1表示使用默认方式即使用看门狗默认实现自动续期RFutureLong ttlRemainingFuture this.tryLockInnerAsync(this.commandExecutor.getConnectionManager().getCfg().getLockWatchdogTimeout(), TimeUnit.MILLISECONDS, threadId, RedisCommands.EVAL_LONG);ttlRemainingFuture.addListener(new FutureListenerLong() {public void operationComplete(FutureLong future) throws Exception {//如果tryLockInnerAsync执行成功if (future.isSuccess()) {//获取过期时间Long ttlRemaining (Long)future.getNow();//过期时间为空表示加锁成功if (ttlRemaining null) {//开启刷新重置过期时间步骤RedissonLock.this.scheduleExpirationRenewal(threadId);}}}});return ttlRemainingFuture;}} // lua脚本尝试抢占锁失败返回锁过期时间T RFutureT tryLockInnerAsync(long leaseTime, TimeUnit unit, long threadId, RedisStrictCommandT command) {this.internalLockLeaseTime unit.toMillis(leaseTime);//直接使用lua脚本发起命令//通过lua脚本可以看出redisson加锁除了使用自定义的名字以外还要使用uuid// 加上当前线程的threadId组合以自定义名字作hash的key使用return this.commandExecutor.evalWriteAsync(this.getName(), LongCodec.INSTANCE, command,//如果该锁未被占有则设置锁设置过期时间过期时间为 internalLockLeaseTime 然后返回nullif (redis.call(exists, KEYS[1]) 0) then redis.call(hset, KEYS[1], ARGV[2], 1); redis.call(pexpire, KEYS[1], ARGV[1]);return nil; end; //如果锁已经被占有判断是否是重入锁如果是重入锁则将value增加1 代表重入并且设置过期时间返回null。if (redis.call(hexists, KEYS[1], ARGV[2]) 1) then redis.call(hincrby, KEYS[1], ARGV[2], 1); redis.call(pexpire, KEYS[1], ARGV[1]); return nil; end; //如果已经被站有所且不是重入锁则返回过期时间return redis.call(pttl, KEYS[1]);,Collections.singletonList(this.getName()), new Object[]{this.internalLockLeaseTime, this.getLockName(threadId)});} 看门狗续命 //看门狗续命机制private void scheduleExpirationRenewal(final long threadId) {//首先会判断该线程是否已经再重置时间的map中仅仅第一次进来是空的。if (!expirationRenewalMap.containsKey(this.getEntryName())) {//使用了看门狗默认的时间30秒 除以3 也就是延迟10秒后执行Timeout task this.commandExecutor.getConnectionManager().newTimeout(new TimerTask() {public void run(Timeout timeout) throws Exception {//判断是否该线程是否还持有锁如果持有返回1并且设置过期时间如果没持有返回0RFutureBoolean future RedissonLock.this.commandExecutor.evalWriteAsync(RedissonLock.this.getName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,if (redis.call(hexists, KEYS[1], ARGV[2]) 1) then redis.call(pexpire, KEYS[1], ARGV[1]); return 1; end; return 0;,Collections.singletonList(RedissonLock.this.getName()), new Object[]{RedissonLock.this.internalLockLeaseTime, RedissonLock.this.getLockName(threadId)});future.addListener(new FutureListenerBoolean() {public void operationComplete(FutureBoolean future) throws Exception {//从map中移除该线程这样下次再调用该方法仍然可以执行RedissonLock.expirationRenewalMap.remove(RedissonLock.this.getEntryName());if (!future.isSuccess()) {RedissonLock.log.error(Cant update lock RedissonLock.this.getName() expiration, future.cause());} else {if ((Boolean)future.getNow()) {//当lua脚本返回1表是true也就是仍然持有锁则递归调用该方法RedissonLock.this.scheduleExpirationRenewal(threadId);}}}});}}, this.internalLockLeaseTime / 3L, TimeUnit.MILLISECONDS);if (expirationRenewalMap.putIfAbsent(this.getEntryName(), task) ! null) {task.cancel();}}}2、unlock 源码 public RFutureVoid unlockAsync(final long threadId) {final RPromiseVoid result new RedissonPromise();//调用lua脚本释放锁RFutureBoolean future this.unlockInnerAsync(threadId);future.addListener(new FutureListenerBoolean() {public void operationComplete(FutureBoolean future) throws Exception {if (!future.isSuccess()) {result.tryFailure(future.cause());} else {Boolean opStatus (Boolean)future.getNow();//如果锁状态为null表示存在异常为正常释放锁之前被别人占领锁了if (opStatus null) {IllegalMonitorStateException cause new IllegalMonitorStateException(attempt to unlock lock, not locked by current thread by node id: RedissonLock.this.id thread-id: threadId);result.tryFailure(cause);} else {//如果返回0.为false 表示可重入锁不取消重置过期时间//返回1 为true表示已解锁取消重置过期时间if (opStatus) {RedissonLock.this.cancelExpirationRenewal();}//解锁result.trySuccess((Object)null);}}}});return result;}protected RFutureBoolean unlockInnerAsync(long threadId) {return this.commandExecutor.evalWriteAsync(this.getName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,//当key不存在表示锁未被持有说明不用解锁了返回1 1在后续表示取消重置过期时间if (redis.call(exists, KEYS[1]) 0) then redis.call(publish, KEYS[2], ARGV[1]); return 1; end; //key存在但是持有锁的线程不是当前线程返回null后面会提出一个异常if (redis.call(hexists, KEYS[1], ARGV[3]) 0) then return nil;end; //锁状态-1后仍然大于0表示可重入锁仍处于锁定状态返回00在后续表示 不做处理仍然重置过期时间local counter redis.call(hincrby, KEYS[1], ARGV[3], -1); if (counter 0) then redis.call(pexpire, KEYS[1], ARGV[2]); return 0; //返回锁状态不大于0正常解锁返回11在后续表示取消重置过期时间else redis.call(del, KEYS[1]); redis.call(publish, KEYS[2], ARGV[1]); return 1; end; return nil;, Arrays.asList(this.getName(), this.getChannelName()), new Object[]{LockPubSub.unlockMessage, this.internalLockLeaseTime, this.getLockName(threadId)});}三、集群环境下潜在问题 在Redis主从架构哨兵模式的环境下业务系统已经成功获取了锁redis写入数据但是正要往从库上存数据时发生主库宕机的情况从库在哨兵的选举下成为了主库而另外一个业务请求再次需要获取锁会直接访问到新的主库而此时新主库是没有锁信息的此时就会出现业务重复的情况。
http://www.w-s-a.com/news/503759/

相关文章:

  • 青海教育厅门户网站有赞商城
  • 网站建设多语种自动翻译插件wordpress谷歌翻译插件
  • 泰安高级网站建设推广wordpress教程 好看
  • 我自己的网站怎么做关键词优化泰安网站建设dxkjw
  • 平面设计做画册用网站泰州seo平台
  • 申请一个域名后怎么做网站evernote wordpress
  • 网站左侧导航栏设计网站开发后台数据怎么来
  • 临西做网站报价网站建设需要写语句吗
  • 建设网站网站首页购物网站开发代码
  • 淘宝客怎么建立网站网站360优化
  • 安徽建海建设工程有限公司网站网站空间和域名价格
  • 农产品网站建设策划哪里有做枪网站的
  • 更改各网站企业信息怎么做张家港企业网站制作
  • 郑州网站建设咨询银川做网站哪家好
  • 微信网站 微信支付合肥seo排名收费
  • 织梦做的网站如何上线广东省广州市番禺区南村镇
  • 网站设计的导航栏怎么做太原有网站工程公司吗
  • 苏州虎丘区建设局网站如何在一个数据库做两个网站
  • 淘宝天猫优惠券网站建设费用腾讯邮箱企业邮箱登录
  • 深圳福田做网站公司海航科技网站建设
  • 网站降权查询wordpress更换文章背景色
  • 大型电商网站开发金融企业网站建设公司
  • 成都营销型网站建设价格化妆品品牌推广方案
  • 深圳公司手机网站制作苏州网站推广哪家好
  • 网站建设开发方式包括购买学校网站建设费计入什么科目
  • 做简单网站的框架图中小微企业查询平台
  • 哪些网站可以免费做产品推广建设建设部网站
  • 网站开发销售怎么做django做网站
  • 淘宝客网站做百度竞价万网域名怎么绑定网站
  • 建设网站找哪个公司北京知名大公司有哪些