Java中的任务超时处理

news/2024/10/7 18:36:29/文章来源:https://www.cnblogs.com/dwcg/p/18316517

Java中的任务超时处理

综述

任务超时处理是编程世界中一个不可或缺且常见的处理机制, 特别是在进行耗时任务时, 如网络请求, 数据库查询, 大规模数据处理等场景。在这些情况下, 为了防止任务因各种不可预测的因素(如网络延迟, 服务器响应超时, 数据量过大等)而无休止地占用宝贵的系统资源, 开发者通常会在任务执行逻辑中引入超时机制.

实现方式

在Java中,超时任务的处理主要通过异常处理、并发控制、线程管理等方式实现。例如,使用java.util.concurrent包中的Future接口和ExecutorService工具类,结合Callable接口和FutureTask,可以方便地设置超时任务。开发人员可以通过设置任务执行的超时时间,一旦任务执行超过设定的时间,系统将抛出TimeoutException,通知开发者任务超时,从而及时采取相应的补救措施。

利用循环计算

利用循环检查时间来处理超时是最直观的思路, 但是这个做法如今几乎没什么人在使用了. 原因有两点, 首先虽然这个做法可以不使用线程/线程池, 但是"耗时操作通常不建议放在主线程中"这一点无论是后端项目还是在android项目中都基本属于共识范畴, 所以仍然需要使用线程/线程池. 其次, 循环检查无法处理因阻塞引起的超时, 这意味着直到线程从阻塞恢复才能执行判断是否退出的语句.

所以无论从性能还是安全性来判断使用 ExecutorService 提供的 api 来实现才是更好的选择. 此处给出示例仅供了解.

public class TimeoutTask {private ExecutorService executorService;private TimeoutTask() {this.executorService = new ThreadPoolExecutor(2,Runtime.getRuntime().availableProcessors() * 2,10, TimeUnit.SECONDS,new ArrayBlockingQueue<>(100),new ThreadPoolExecutor.CallerRunsPolicy());}private static class SingletonHolder {private static final TimeoutTask instance = new TimeoutTask();}//单例模式public static TimeoutTask getInstance() {return SingletonHolder.instance;}private static String formatTime(long time) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");return sdf.format(new Date(time));}public void timeoutWithLoop(long millisecondLimit) {executorService.execute(new Runnable() {@Overridepublic void run() {long startTime = System.currentTimeMillis();for (; ; ) {var currentTime = System.currentTimeMillis();System.out.println("当前的时间: " + formatTime(currentTime));//这里使用thread.sleep模拟耗时操作try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}if (currentTime - startTime > millisecondLimit) {//为了方便测试代码运行结束自动关闭额外使用了shutdownexecutorService.shutdown();break;}}}});}
}public class Main {public static void main(String[] args) {TimeoutTask.getInstance().timeoutWithLoop(4000);}
}

另外, 通过循环处理超时任务还有一个变种做法, 那就是通过 Timer 或者其他延时api控制某个 AtomicBoolean 格式的flag进行转变, 在循环中通过检查flag来判断是否超时并跳出. 这里额外再提一句, 示例就不给出了.

当然, 这个变种做法依然存在此前提到的两种问题, 同样不推荐, 仅供了解.

利用 future.get() 和 future.cancel() 方法

这应该是当前处理异步任务超时情况下最好的处理方式, 通过 executorService.submit() 获取 future , 通过 future.get() 设置超时期限, 再在 TimeoutException 触发时通过 future.cancel() 取消超时任务.

public class TimeoutTask {private ExecutorService executorService;private TimeoutTask() {this.executorService = new ThreadPoolExecutor(2,Runtime.getRuntime().availableProcessors() * 2,10, TimeUnit.SECONDS,new ArrayBlockingQueue<>(100),new ThreadPoolExecutor.CallerRunsPolicy());}private static class SingletonHolder {private static final TimeoutTask instance = new TimeoutTask();}//单例模式public static TimeoutTask getInstance() {return SingletonHolder.instance;}private static String formatTime(long time) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");return sdf.format(new Date(time));}public void timeoutWithFuture(long targetTime) {Future<?> future = executorService.submit(() -> {try {TimeUnit.MILLISECONDS.sleep(8000);var awaitEndTime = System.currentTimeMillis();System.out.println("通过condition.await()等待结束时间: "+ formatTime(awaitEndTime) + "这一行不应该被打印");} catch (InterruptedException e) {throw new RuntimeException(e);}});try {var startTime = System.currentTimeMillis();System.out.println("超时示例开始时间: "+ formatTime(startTime));future.get(targetTime, TimeUnit.MILLISECONDS);} catch (TimeoutException e) {// 超时处理var endTime = System.currentTimeMillis();System.out.println("任务按照预想超时结束, 结束时间: "+ formatTime(endTime));future.cancel(true);} catch (ExecutionException | InterruptedException e) {System.out.println("报错信息: "+e.getMessage());} finally {executorService.shutdown();}}
}

总结

综上所述, Java中的任务超时处理是一个非常重要且常见的编程实践. 处理这个问题时, 利用Java并发包中的Future接口和ExecutorService工具类基本可以被看作常规场景下的最优选. 这一做法简单有效. 另外, 在中型以上的项目中还可以进一步拓展, 将超时处理封装成类, 通过自定义的方法, 类似 executeWithTimeout(callable timeOutCallback, long timeInMillisecond, runnable onTimeOut){} 这样的封装. 这样可以不需要每次使用时都写一大堆套路代码, 减小工作量.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/809540.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

React 中的 diff 算法

React diff为什么使用虚拟 DOM ? 浏览器在处理 DOM 的时候会很慢,处理 JavaScript 会很快,页面复杂的时候,频繁操作 DOM 会有很大的性能开销(每次数据变化都会引起整个 DOM 树的重绘和重排)。 为了避免频繁操作 DOM,React 会维护两个虚拟 DOM,如果有数据更新,会借此计…

20222315 2024-2025-1 《网络与系统攻防技术》实验一实验报告

1.实验内容 1.掌握反汇编与十六进制编程器 2.能正确修改机器指令改变程序执行流程 3.能正确构造payload进行bof攻击 2.实验过程 1.直接修改程序机器指令,改变程序执行流程 将pwn1文件下载至kali中并将pwn1文件改名为pwn20222315,并将其内容复制到pwn2反汇编文件objdump -d…

多校A层冲刺NOIP2024模拟赛03

多校A层冲刺NOIP2024模拟赛03\(T1\) A. 五彩斑斓(colorful) \(90/100pts\)部分分\(20pts\) :枚举左上 \((k,h)\) 、右下端点 \((i,j)\) ,时间复杂度为 \(O(n^{2}m^{2})\) 。 \(90/100pts\) :当 \(a_{i,j} \ne a_{k,j}\) 时任意的 \(h \in [1,j]\) 都符合题意、不妨钦定 \(…

Word中 Endnote 引用标蓝色

1. 打开word中的endnote加载项。如图所示,勾选这两个设置。 确认后会自动变为超链接,显示蓝色以及下划线。 2. 在样式设置中,将超链接的下划线取消。之后就会只显示蓝色引用。 结果显示:

中国大学生程序设计竞赛(秦皇岛)正式赛东北大学秦皇岛分校(SMU Autumn 2024 Team Round 1)

中国大学生程序设计竞赛(秦皇岛)正式赛东北大学秦皇岛分校(SMU Autumn 2024 Team Round 1) Problem A. 贵校是构造王国吗 I 思路 官方题解很清晰明了。代码 #include <bits/stdc++.h> using namespace std; #define int long long #define endl \n #define PII pair&…

多校 A 层冲刺 NOIP2024 模拟赛 03

多校 A 层冲刺 NOIP2024 模拟赛 03 T1 五彩斑斓(colorful) 签到题 直接暴力枚举是 \(O(n^4)\) ,考虑使用 \(bitset\) 优化,对每个点开个 \(bitset\),预处理它所在一行它及它之前相同颜色的位置,这样就只用枚举另一个点所在列,时间复杂度为 \(O(n^3+\frac{n^4}{w})\)。 T…

在浏览器上访问媒体资源配置【文件上传】

1.根urls.py文件中 from django.contrib import admin from django.urls import path, include, re_path from django.views.static import serve from django.conf import settingsurlpatterns = [# path(admin/, admin.site.urls),path(api/shipper/, include(apps.shipper.u…

高级程序语言设计第二次作业

姓名:袁志华 班级:软件工程2班 学号:102400231 班级网址:https://edu.cnblogs.com/campus/fzu/2024C 作业网址:https://edu.cnblogs.com/campus/fzu/2024C/homework/13282 图片: 第一题: 第二题: 第三题: 第四题: 第五题: 第六题: 第七题: 第八题:程序清单: 3.1…

macOS Sequoia 15.0.1 (24A348) 正式版 ISO、IPSW、PKG 下载

macOS Sequoia 15.0.1 (24A348) 正式版 ISO、IPSW、PKG 下载macOS Sequoia 15.0.1 (24A348) 正式版 ISO、IPSW、PKG 下载 iPhone 镜像、Safari 浏览器重大更新和 Apple Intelligence 等众多全新功能令 Mac 使用体验再升级 请访问原文链接:https://sysin.org/blog/macOS-Sequoi…

人群聚集监测预警系统

人群聚集监测预警系统采用AI视频智能分析技术,人群聚集监测预警系统通过在工地、工厂等场所已经安装监控摄像头,人群聚集监测预警系统对人员聚集情况进行实时监测,当人群聚集过于密集时,系统将自动发出警报,人群聚集监测预警系统并通过人工智能算法对人员的状态进行识别和…

智能烟火识别预警软件

智能烟火识别预警软件采用人工智能技术,智能烟火识别预警软件在工厂、工地等场所利用已经安装的摄像头,智能烟火识别预警软件对场内的烟花爆竹进行实时监测。当场内出现烟花爆竹时,智能烟火识别预警软件将自动发出警报,并通过人工智能算法通知现场管理人员进行处理。智能烟…

脱岗监测预警系统

脱岗监测预警系统可以通过对工人的位置进行实时监测,脱岗监测预警系统识别是否存在脱岗行为,并及时发出警报。脱岗监测预警系统在工作过程中,如果工人离开其工作位置,脱岗监测预警系统会自动识别并发出警报,提醒管理人员采取措施防止事故的发生。脱岗监测预警系统可以通过…