新闻详情

新闻详情

首页 / 资讯中心 / 详情

Java进阶篇之ReentrantLock:给等待设置期限,让取消及时生效

发布时间:2026/11/14 4:04:04来源:尧图网络
Java进阶篇之ReentrantLock:给等待设置期限,让取消及时生效
前一篇讨论了ConcurrentHashMap怎样协调共享数据。如果一次操作需要同时维护多个字段或者需要明确控制等待时间就要重新审视锁的使用方式。之前的《Java进阶篇之同步与锁》介绍过ReentrantLock的基本加锁与释放。今天继续往下走请求已经超时线程还应该排队吗任务被取消等待锁的线程能否及时离开没有拿到锁finally里还能调用unlock吗本文使用Java 21围绕等待、取消和释放展开不涉及分布式锁。一、先给等待选一种策略ReentrantLock提供了几种不同的获取方式。选择方法之前可以先问业务这次操作愿意等多久是否需要响应取消获取方式获取不到时等待期间能否通过中断退出lock()继续等待不会因中断而结束锁等待tryLock()立即返回false没有阻塞等待阶段tryLock(timeout, unit)最多等待指定时间超时返回false可以抛出InterruptedExceptionlockInterruptibly()等待获取可以抛出InterruptedException这里的“最多等待”指锁获取的超时语义线程调度可能让实际返回时刻稍晚它也不限制拿到锁后业务代码的执行时长。方法语义以Java 21的ReentrantLock文档为准。例如一个接口总预算为800ms锁获取已经消耗300ms那么后面的数据库操作不能再无条件获得完整800ms。调用链预算需要向下传递给每一步单独设置相同超时可能累加出更长的总耗时。二、超时与中断分别解决什么问题超时表达“我只愿意等到这里”。获取失败后可以返回繁忙、使用已有结果或者交给上层决定是否重试。中断表达外部发来的协作式取消信号。使用lockInterruptibly或带超时的tryLock时等待线程可以通过异常路径结束当前尝试。中断不会自动回滚已经完成的业务修改。图里的门代表临界区入口。计时器归零和收到取消信号都可能让等待者离开已经进入临界区的线程仍需负责自己的释放与收尾。异常处理也要明确职责能够继续向上抛出时保留InterruptedException在Runnable等不允许抛出受检异常的边界通常恢复中断标记并退出本次任务避免悄悄吞掉取消请求。三、完整示例验证超时和取消下面用主线程持有同一把锁分别启动两个工作线程。主线程在它们结束之前不释放锁因此结果不依赖“碰巧先运行哪一个线程”。CountDownLatch只用于确认第二个线程已经启动不负责制造锁竞争。保存为LockWaitingDemo.javaimportjava.util.concurrent.CountDownLatch;importjava.util.concurrent.TimeUnit;importjava.util.concurrent.locks.ReentrantLock;publicclassLockWaitingDemo{publicstaticvoidmain(String[]args)throwsInterruptedException{ReentrantLocklocknewReentrantLock();lock.lock();try{ThreadtimednewThread(()-{try{if(!lock.tryLock(100,TimeUnit.MILLISECONDS)){System.out.println(timed: timeout);return;}try{System.out.println(timed: acquired);}finally{lock.unlock();}}catch(InterruptedExceptione){Thread.currentThread().interrupt();System.out.println(timed: cancelled);}});timed.start();timed.join();CountDownLatchstartednewCountDownLatch(1);ThreadcancellablenewThread(()-{started.countDown();try{lock.lockInterruptibly();try{System.out.println(cancel: acquired);}finally{lock.unlock();}}catch(InterruptedExceptione){Thread.currentThread().interrupt();System.out.println(cancel: interruptedThread.currentThread().isInterrupted());}});cancellable.start();started.await();cancellable.interrupt();cancellable.join();}finally{lock.unlock();}System.out.println(main: lockedlock.isLocked());}}运行命令javac LockWaitingDemo.javajavaLockWaitingDemo输出timed: timeout cancel: interruptedtrue main: lockedfalse第一行来自等待超时。第二个线程可能在调用lockInterruptibly前就收到中断也可能已经开始等待这两种时序都会走取消路径。catch恢复标记后isInterrupted返回true。这里让主线程持锁并join工作线程是为了构造有限等待的演示条件。不要把第二个线程改为lock后照搬到业务它会等待主线程释放主线程又等待它结束从而互相卡住。四、finally必须对应一次成功获取最容易写错的是下面这种结构// 错误示意获取阶段抛出异常也会执行unlocktry{lock.lockInterruptibly();// 业务操作}finally{lock.unlock();}在尚未持有该锁的情况下被中断finally会尝试释放不属于当前线程的锁可能让IllegalMonitorStateException掩盖原来的取消原因。更清楚的结构是先成功获取再进入负责释放的trylock.lockInterruptibly();try{// 仅在拿到锁后执行}finally{lock.unlock();}带超时的版本同样先判断返回值。返回false的分支直接结束成功分支才配对unlock。这种写法把锁的所有权直接体现在代码结构里也符合Lock接口建议的释放模式。五、使用时再检查三个边界缩短持锁区间。把耗时日志、远程调用和可提前计算的内容移出临界区确实需要共同保护的状态则在锁内一起检查和修改。读取与修改的边界必须由业务不变量决定。取消后不要立即无限重试。如果上层已经取消任务重新排队只会让取消失去意义。超时重试也需要次数限制与剩余预算不能在循环里不断重置期限。重入也需要配对释放。同一线程可以再次获取ReentrantLock但每次成功获取都要对应一次unlock。为排查问题读取isLocked等状态可以辅助观察不应据此替代真正的获取操作观察结束后其他线程仍可能改变状态。六、 思维导图ReentrantLock等待控制获取策略立即尝试限时等待可中断等待退出原因超时返回false中断异常释放规则成功获取再进入tryfinally配对unlock业务边界传递剩余预算取消后结束任务七、总结总结要点等待策略要与业务预算一致。立即失败、限时等待和可中断等待分别适用于不同的调用需求。获取与释放应在结构上配对。先确认获取成功再进入finally负责的范围避免释放未持有的锁。取消处理需要贯穿调用链。中断到达之后线程要结束当前任务或向上交还处理权已有业务结果是否回滚需要另行设计。下一篇继续学习Condition线程怎样等待业务条件以及为什么await通常要放在while循环中。如果你觉得这篇文章对你有所帮助欢迎点赞、收藏、分享
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

【外设】之大彩串口显示屏 2026/11/14 3:51:47

【外设】之大彩串口显示屏

大彩串口屏初步使用 1 .官网下载 STM32 屏幕 GUI 设计资料 http://www.gz-dc.com/category/typeid/4112 找到 STM32 Keil 工程,移植相关代码因项目而异进行移植,由于项目简单,本人只对用到的指令接口进行修改。 比如:注意事项&…

阅读更多 →
无法下载Windows系统iso文件 2026/11/12 23:59:09

无法下载Windows系统iso文件

当我遇到这个问题的时候,我打开了一个网站: 登录 然后我打算下载的时候: 突然那个官方的连接就可以下载了:

阅读更多 →
【清华代码熊】DeepSeek V4.1 Flash 后训练详解 2026/11/13 10:09:00

【清华代码熊】DeepSeek V4.1 Flash 后训练详解

📌 上期解析了 DeepSeek V4.1 Flash 模型架构改进,本期解析 DeepSeek V4.1 Flash 预训练/后训练技术: 🌟 预训练:45T 文本 多模态混合语料、直接训练 sparse attention(取消 DeepSeek V4 的 dense 冷启动&…

阅读更多 →
Shuffle-R1: Efficient RL framework for Multimodal Large Language Models via Data-centric Dynamic ... 2026/11/13 13:31:48

Shuffle-R1: Efficient RL framework for Multimodal Large Language Models via Data-centric Dynamic ...

文章主要内容和创新点 主要内容 本文聚焦于多模态大语言模型(MLLM)强化学习(RL)训练中的效率问题,提出了一个名为Shuffle-R1的框架。研究发现,当前RL训练存在两个关键缺陷: 优势值坍缩(Advantage Collapsing):批次中大多数优势值集中在零附近,导致有效梯度信号被淹…

阅读更多 →
PRvL: Quantifying the Capabilities and Risks of Large Language Models for PII Redaction 2026/11/13 16:11:45

PRvL: Quantifying the Capabilities and Risks of Large Language Models for PII Redaction

一、文章主要内容总结 本文聚焦于利用大型语言模型(LLMs)实现个人身份信息(PII)脱敏的研究,旨在解决传统脱敏方法(如基于规则的系统、领域特定命名实体识别(NER)模型)泛化能力差、跨格式/跨语境适应性弱的问题。 研究通过全面评估多种LLM架构(包括密集型LLM(D-LLM…

阅读更多 →
LLaVA-RE: Binary Image-Text Relevancy Evaluation with Multimodal Large Language Model 2026/11/14 3:51:43

LLaVA-RE: Binary Image-Text Relevancy Evaluation with Multimodal Large Language Model

文章主要内容和创新点 主要内容 本文聚焦于二进制图像-文本相关性评估任务(判断图像与文本“相关”或“不相关”),针对该任务中文本格式多样、相关性定义随场景变化等挑战,提出了基于多模态大语言模型(MLLM)的解决方案LLaVA-RE。 模型设计:LLaVA-RE基于LLaVA 1.5架构,…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉