Java并发框架——AQS超时机制

简介: AQS框架提供的另外一个优秀机制是锁获取超时的支持,当大量线程对某一锁竞争时可能导致某些线程在很长一段时间都获取不了锁,在某些场景下可能希望如果线程在一段时间内不能成功获取锁就取消对该锁的等待以提高性能,这时就需要用到超时机制。
AQS框架提供的另外一个优秀机制是锁获取超时的支持,当大量线程对某一锁竞争时可能导致某些线程在很长一段时间都获取不了锁,在某些场景下可能希望如果线程在一段时间内不能成功获取锁就取消对该锁的等待以提高性能,这时就需要用到超时机制。在JDK1.5之前还没有juc工具,当时的并发控制职能通过JVM内置的synchronized关键词实现锁,但对一些特殊要求却力不从心,例如超时取消控制。JDK1.5开始引入juc工具完美解决了此问题,而这正得益于并发基础框架AQS提供了超时的支持。
为了更精确地保证时间间隔统计的准确性,实现时使用了System.nanoTime()更为精确的方法,它能精确到纳秒级别。超时机制的思想就是在不断进行锁竞争的同时记录竞争的时间,一旦时间段超过指定的时间则停止轮询直接返回,返回前对等待队列中对应节点进行取消操作。往下看实现的逻辑,
if(尝试获取锁失败) { 
long lastTime = System.nanoTime();
    创建node
    使用CAS方式把node插入到队列尾部
    while(true){
    if(尝试获取锁成功 并且 node的前驱节点为头节点){
把当前节点设置为头节点
    跳出循环
}else{
    if (nanosTimeout <= 0){
取消等待队列中此节点
跳出循环
}
    使用CAS方式修改node前驱节点的waitStatus标识为signal
    if(修改成功)
        if(nanosTimeout > spinForTimeoutThreshold)
        阻塞当前线程nanosTimeout纳秒
    long now = System.nanoTime();
    nanosTimeout -= now - lastTime;
    lastTime = now;
}
}
上面正是在前面章节锁的获取逻辑中添加超时处理,核心逻辑是不断循环减去处理的时间消耗,一旦小于0就取消节点并跳出循环,其中有两点必须要注意,一个是真正的阻塞时间应该是扣除了竞争入队的时间后剩余的时间,保证阻塞事件的准确性,我们可以看到每次循环都会减去相应的处理时间;另外一个是关于spinForTimeoutThreshold变量阀值,它是决定使用自旋方式消耗时间还是使用系统阻塞方式消耗时间的分割线,juc工具包作者通过测试将默认值设置为1000ns,即如果在成功插入等待队列后剩余时间大于1000ns则调用系统底层阻塞,否则不调用系统底层,取而代之的是仅仅让之在Java应用层不断循环消耗时间,属于优化的措施。

至此AQS框架在获取锁的过程中提供了超时机制,超时的支持让Java在并发方面提供了更完善的机制,更多的并发策略满足开发者更多需求。


点击订购作者书籍《Tomcat内核设计剖析》




目录
相关文章
|
2月前
|
安全 前端开发 Java
《深入理解Spring》:现代Java开发的核心框架
Spring自2003年诞生以来,已成为Java企业级开发的基石,凭借IoC、AOP、声明式编程等核心特性,极大简化了开发复杂度。本系列将深入解析Spring框架核心原理及Spring Boot、Cloud、Security等生态组件,助力开发者构建高效、可扩展的应用体系。(238字)
|
3月前
|
人工智能 Java 开发者
阿里出手!Java 开发者狂喜!开源 AI Agent 框架 JManus 来了,初次见面就心动~
JManus是阿里开源的Java版OpenManus,基于Spring AI Alibaba框架,助力Java开发者便捷应用AI技术。支持多Agent框架、网页配置、MCP协议及PLAN-ACT模式,可集成多模型,适配阿里云百炼平台与本地ollama。提供Docker与源码部署方式,具备无限上下文处理能力,适用于复杂AI场景。当前仍在完善模型配置等功能,欢迎参与开源共建。
1530 58
阿里出手!Java 开发者狂喜!开源 AI Agent 框架 JManus 来了,初次见面就心动~
|
2月前
|
Java 大数据 Go
从混沌到秩序:Java共享内存模型如何通过显式约束驯服并发?
并发编程旨在混乱中建立秩序。本文对比Java共享内存模型与Golang消息传递模型,剖析显式同步与隐式因果的哲学差异,揭示happens-before等机制如何保障内存可见性与数据一致性,展现两大范式的深层分野。(238字)
80 4
|
2月前
|
缓存 安全 Java
如何理解Java中的并发?
Java并发指多任务交替执行,提升资源利用率与响应速度。通过线程实现,涉及线程安全、可见性、原子性等问题,需用synchronized、volatile、线程池及并发工具类解决,是高并发系统开发的关键基础。(238字)
217 4
|
2月前
|
存储 安全 Java
《数据之美》:Java集合框架全景解析
Java集合框架是数据管理的核心工具,涵盖List、Set、Map等体系,提供丰富接口与实现类,支持高效的数据操作与算法处理。
|
2月前
|
消息中间件 缓存 Java
Spring框架优化:提高Java应用的性能与适应性
以上方法均旨在综合考虑Java Spring 应该程序设计原则, 数据库交互, 编码实践和系统架构布局等多角度因素, 旨在达到高效稳定运转目标同时也易于未来扩展.
130 8
|
2月前
|
存储 算法 安全
Java集合框架:理解类型多样性与限制
总之,在 Java 题材中正确地应对多样化与约束条件要求开发人员深入理解面向对象原则、范式编程思想以及JVM工作机理等核心知识点。通过精心设计与周密规划能够有效地利用 Java 高级特征打造出既健壮又灵活易维护系统软件产品。
98 7
|
3月前
|
SQL Java 数据库连接
区分iBatis与MyBatis:两个Java数据库框架的比较
总结起来:虽然从技术角度看,iBATIS已经停止更新但仍然可用;然而考虑到长期项目健康度及未来可能需求变化情况下MYBATISS无疑会是一个更佳选择因其具备良好生命周期管理机制同时也因为社区力量背书确保问题修复新特征添加速度快捷有效.
218 12
|
7月前
|
机器学习/深度学习 消息中间件 存储
【高薪程序员必看】万字长文拆解Java并发编程!(9-2):并发工具-线程池
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发编程中的强力并发工具-线程池,废话不多说让我们直接开始。
261 0
|
7月前
|
缓存 安全 Java
【高薪程序员必看】万字长文拆解Java并发编程!(3-1):并发共享问题的解决与分析
活锁:多个线程相互影响对方退出同步代码块的条件而导致线程一直运行的情况。例如,线程1的退出条件是count=5,而线程2和线程3在其代码块中不断地是count进行自增自减的操作,导致线程1永远运行。内存一致性问题:由于JIT即时编译器对缓存的优化和指令重排等造成的内存可见性和有序性问题,可以通过synchronized,volatile,并发集合类等机制来解决。这里的线程安全是指,多个线程调用它们同一个实例的方法时,是线程安全的,但仅仅能保证当前调用的方法是线程安全的,不同方法之间是线程不安全的。
136 0