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

如何做招生网站深圳市城市建设管理局

如何做招生网站,深圳市城市建设管理局,旅游营销型网站建设,免费制作企业小程序引言 有加锁自然就有解锁,本篇则将围绕锁的释放锁Lua脚本进行深入剖析,另外,还将对阻塞和非阻塞两张方式分别如何获取锁进行比较。 可重入锁之释放锁 这里我们依然是按照步骤来看看释放锁是如何执行的。 1.首先从入口方法开始: …

引言

有加锁自然就有解锁,本篇则将围绕锁的释放锁Lua脚本进行深入剖析,另外,还将对阻塞和非阻塞两张方式分别如何获取锁进行比较。

可重入锁之释放锁

这里我们依然是按照步骤来看看释放锁是如何执行的。

1.首先从入口方法开始:

public void unlock() {try {get(unlockAsync(Thread.currentThread().getId()));} catch (RedisException e) {if (e.getCause() instanceof IllegalMonitorStateException) {throw (IllegalMonitorStateException) e.getCause();} else {throw e;}}
}// 异步解锁方法
public RFuture<Void> unlockAsync(long threadId) {// 调用解锁的 Lua 脚本RFuture<Boolean> future = unlockInnerAsync(threadId);return future.thenAccept((opStatus) -> {// 解锁成功,取消看门狗续期cancelExpirationRenewal(threadId);// 如果解锁的不是自己的锁,抛出异常if (!opStatus) {throw new IllegalMonitorStateException("attempt to unlock lock, not locked by current thread by node id: "+ id + " thread-id: " + threadId);}});
}

2.核心解锁Lua脚本实现:

protected RFuture<Boolean> unlockInnerAsync(long threadId) {return commandExecutor.evalWriteAsync(getName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,// 检查锁是否存在"if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) then " +"return nil;" +"end; " +// 计算当前线程的重入次数"local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1); " +// 如果重入次数还大于0,则更新过期时间"if (counter > 0) then " +"redis.call('pexpire', KEYS[1], ARGV[2]); " +"return 0; " +"end; " +// 重入次数为0,删除锁"redis.call('del', KEYS[1]); " +// 发布锁释放的消息"redis.call('publish', KEYS[2], ARGV[1]); " +"return 1; ",// 脚本参数Arrays.asList(getName(),                // KEYS[1] 锁名称getChannelName(),         // KEYS[2] 发布订阅的channel名称RedissonLockEntry.UNLOCK_MESSAGE,    // ARGV[1] 解锁消息internalLockLeaseTime,    // ARGV[2] 锁过期时间getLockName(threadId)     // ARGV[3] 线程标识));
}

3.梳理流程

  • 首先进行解锁的前置检查:检查是否存在对应线程的锁,如果不存在,则返回nil。
  • 如果获取锁成功,则:处理重入计数,即将当前线程的重入计数减1;如果重入计数还大于0,表示还有重入,则重新设置过期时间,返回0则表示锁还未完全释放。
  • 完全释放锁,即:当计数器为0,删除整个锁并发布锁释放的消息,通知等待的线程,返回1则表示锁已完全释放。
  • 后续处理,需要:解锁成功后取消看门狗续期和处理异常情况。

可重入锁之阻塞和非阻塞获取锁

redisson提供了两种不同方式获取锁的封装,我们这里比较讲下:

1.非阻塞获取锁 (tryLock)

public boolean tryLock() {return tryLock(-1, -1, TimeUnit.MILLISECONDS);
}// 带超时的非阻塞获取锁
public boolean tryLock(long waitTime, TimeUnit unit) throws InterruptedException {return tryLock(waitTime, -1, unit);
}// 核心实现
public boolean tryLock(long waitTime, long leaseTime, TimeUnit unit) throws InterruptedException {long time = unit.toMillis(waitTime);long current = System.currentTimeMillis();long threadId = Thread.currentThread().getId();// 第一次尝试获取锁Long ttl = tryAcquire(leaseTime, unit, threadId);// ttl为空表示获取成功if (ttl == null) {return true;}// 如果没有等待时间,直接返回失败if (time <= 0) {return false;}// 计算剩余等待时间time -= System.currentTimeMillis() - current;if (time <= 0) {return false;}// 订阅锁释放通知RFuture<RedissonLockEntry> subscribeFuture = subscribe(threadId);if (!subscribeFuture.await(time, TimeUnit.MILLISECONDS)) {return false;}try {while (true) {long currentTime = System.currentTimeMillis();ttl = tryAcquire(leaseTime, unit, threadId);// 获取成功if (ttl == null) {return true;}// 超过等待时间,返回失败time -= System.currentTimeMillis() - currentTime;if (time <= 0) {return false;}// 等待锁释放通知currentTime = System.currentTimeMillis();if (ttl >= 0 && ttl < time) {getEntry(threadId).getLatch().tryAcquire(ttl, TimeUnit.MILLISECONDS);} else {getEntry(threadId).getLatch().tryAcquire(time, TimeUnit.MILLISECONDS);}time -= System.currentTimeMillis() - currentTime;if (time <= 0) {return false;}}} finally {// 取消订阅unsubscribe(subscribeFuture, threadId);}
}

2.阻塞获取锁 (Lock)

public void lock() {try {lock(-1, null, false);} catch (InterruptedException e) {throw new IllegalStateException();}
}// 带超时的阻塞获取锁
public void lock(long leaseTime, TimeUnit unit) {try {lock(leaseTime, unit, false);} catch (InterruptedException e) {throw new IllegalStateException();}
}// 核心实现
private void lock(long leaseTime, TimeUnit unit, boolean interruptibly) throws InterruptedException {long threadId = Thread.currentThread().getId();// 第一次尝试获取锁Long ttl = tryAcquire(leaseTime, unit, threadId);if (ttl == null) {return;}// 订阅锁释放通知RFuture<RedissonLockEntry> subscribeFuture = subscribe(threadId);if (interruptibly) {subscribeFuture.syncUninterruptibly();} else {subscribeFuture.sync();}try {while (true) {ttl = tryAcquire(leaseTime, unit, threadId);// 获取成功if (ttl == null) {break;}// 等待锁释放通知if (ttl >= 0) {try {getEntry(threadId).getLatch().await(ttl, TimeUnit.MILLISECONDS);} catch (InterruptedException e) {if (interruptibly) {throw e;}getEntry(threadId).getLatch().await();}} else {if (interruptibly) {getEntry(threadId).getLatch().await();} else {getEntry(threadId).getLatch().awaitUninterruptibly();}}}} finally {// 取消订阅unsubscribe(subscribeFuture, threadId);}
}

3.两种方式的关键区别:

  • 等待策略:

    tryLock:有限时间等待,超时返回false

    lock:无限等待直到获取到锁

  • 返回值:

    tryLock:返回boolean,表示是否获取成功

    lock:无返回值,要么获取成功,要么一直等待

  • 中断处理:

    tryLock:支持中断

    lock:默认不响应中断,但可以通过lockInterruptibly方法支持中断

小结

关于可重入锁的相关源码刨析就告一段落了,在接下来的篇章中我们将继续分析不同类型锁的实现。


文章转载自:

http://l7I2iAJU.zdpjr.cn
http://f1mkteb9.zdpjr.cn
http://bsjYUER5.zdpjr.cn
http://GCozFAFH.zdpjr.cn
http://obNAv6va.zdpjr.cn
http://ib6dsOva.zdpjr.cn
http://8nd3f0ZK.zdpjr.cn
http://dDk6JWQa.zdpjr.cn
http://Kr8OzvDs.zdpjr.cn
http://NpsZhlum.zdpjr.cn
http://QxNsLAXs.zdpjr.cn
http://w5GX1h4j.zdpjr.cn
http://qfMLKRRN.zdpjr.cn
http://l65g9syt.zdpjr.cn
http://l7qojQHe.zdpjr.cn
http://4QKkZu67.zdpjr.cn
http://zuDtqxBV.zdpjr.cn
http://wL53bkP1.zdpjr.cn
http://zYCXMI3G.zdpjr.cn
http://1ptUhKPP.zdpjr.cn
http://brRP4Oan.zdpjr.cn
http://ZOOR2noo.zdpjr.cn
http://ahhJiEyn.zdpjr.cn
http://LiilrGVy.zdpjr.cn
http://iWMQt0lU.zdpjr.cn
http://Wp01XplT.zdpjr.cn
http://2qJJaJdU.zdpjr.cn
http://dlvpiV82.zdpjr.cn
http://SL43w9EN.zdpjr.cn
http://f9cW5nSg.zdpjr.cn
http://www.dtcms.com/wzjs/731108.html

相关文章:

  • 泰安网站建设个人工作室织梦网站必须下载
  • 重庆网站建设定制谷歌seo关键词优化
  • 长春人才网招聘余姚网站seo运营
  • 网站建设中数据字典招标网平台
  • 多域名指向同一网站内网网站建设改版方案
  • ppt模板下载免费素材网站注册微信
  • 安徽省建设厅执业资格注册中心网站网络营销推广公司网站有哪些
  • 二维码制作app怎么关闭seo查询
  • 建设家居网站站酷网站建设
  • win7记事本做网站网页设计作品展
  • 网站建设公司怎么宣传国内软件开发
  • 如何利用网站做产品推广网页设计与制作项目教程陈义文
  • 手机网站建设服务器长沙app网站开发
  • 百度网址大全网站网站制作 常见问题
  • 苏州网站建设网站网站设计中的div是什么
  • 2018年主流网站开发语言电子商务专升本可以报什么专业
  • 江苏有哪些做网站建设的公司企业网站建设与维护
  • 高中信息技术网站设计规划晋江住房和城乡建设局网站
  • 建网站主要工具用了采集站域名做网站
  • 有空间与域名 怎么做网站网站建设中网页代码
  • 专做专业课视频的网站网站布局策划的流程图
  • 贵州国龙翔建设有限公司网站男通网站哪个好用
  • 热门的网站模板下载北京app搭建
  • python云服务器网站开发实例网站运营
  • 在线免费货源网站入口网站信息更新如何做
  • 外贸网站建设哪里做得好企业网站制作的软件
  • 贵州网站制作设计公司哪家好延边省建设局网站官网
  • 网站导航仿站西安短视频代运营
  • 如何建设网站建设现在做个网站要多少钱
  • 福建设备公司网站商丘建网站