如何控制方法的调用Timeout超时,并主动中断调用请求
1|0前言
在我们实际开发过程中,我们经常遇到一些场景:
1、如果调用方法超过1秒,就应该停止调用,不要一直阻塞下去,防止把本身的服务资源搞挂。
2、在不可预知可能出现死锁/死循环的代码,要加上时间的阀值,避免阻塞。
很多开源框架都会有超时响应的设置;如果是我们自己开发的服务,怎么能做到这点呢?
2|0JDK的Future
在jdk中有个future类,里面有获取等待超时的方法
本文不重点介绍future方法,可自行网补
3|0Guava中的超时
Google开源的Guava工具包,还是比较强大的;里面即包含了超时的控制。里面有个
TimeLimiter 是个接口,下面有两个子类,
FakeTimeLimiter, 常用于debug时,限制时间超时调试
SimpleTimeLimiter 常用于正式方法中,调用方法超时,即抛出异常
4|0SimpleTimeLimiter
这个类有2种方式实现超时的控制,代理模式和回调模式
5|0一、基于代理模式
Guava采用的是JDK动态代理实现的AOP拦截,所以代理类必须实现一个接口。可以达到对类中所有的方法进行超时控制。
pom依赖
定义接口
定义了一个学生服务接口
接口实现
实现了根据id获取姓名,以及获取爱好
获取姓名方法需耗时3秒;获取爱好方法需耗时10秒
如何调用
上面是调用代码,核心代码如下
利用SimpleTimeLimiter新建了代理对象studentServiceProxy,并传递了6秒的超时设置。
我们只要在调用方法的时候,捕获TimeoutException异常即可。
执行结果如下
上面的结果,获取爱好方法超过了6秒就中断了,并抛出了异常
我们发现配置了超时时间6秒后,StudentServiceProxy代理对象的所有方法都是6秒超时
6|0解耦合,重构代码
我们发现上面的代码需要在调用方实现SimpleTimeLimiter的配置,感觉耦合度高了点。我们可以把代码改造一下。
接口定义
接口实现
调用方
这样的改造就非常好了,调用方不需要关心具体的超时实现,直接调用即可。
7|0二、基于回调模式
上面的代理模式是针对类的,回调模式是可以针对某段代码的。
上面代码中,定义Callable使用业务代码。执行结果如下
8|0线程池定义
SimpleTimeLimiter是可以自定义线程池的
执行结果如下
9|0总结
SimpleTimeLimiter对象本质上也是使用了JDK中的Future对象实现了Timeout
源码如下:
被Guava封装了一下,使用起来特别方便。小伙伴可自行尝试。
__EOF__

本文链接:https://www.cnblogs.com/caicz/p/16729880.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人