一个用Kotlin编写简易的串行任务调度器
引言
由于项目中有处理大量后台任务并且串行执行的需求,特意写了一个简易的任务调度器,方便监控每个任务执行和异常情况,任务之间互不影响。正如上所述,Kotlin中的TaskScheduler类提供了一个强大的解决方案,用于使用ScheduledExecutorService异步地排队和执行任务。
使用方法
1.初始化:
val taskListener = object : TaskScheduler.TaskListener {override fun beforeExecute(task: TaskScheduler.NamedRunnable) {println("开始任务:${task.name}")}override fun afterExecute(task: TaskScheduler.NamedRunnable, exception: Exception?) {println("完成任务:${task.name},异常:$exception")}
}
val scheduler = TaskScheduler(taskListener, 5)
2.提交任务:
scheduler.submit("加载数据") {// 加载数据的代码
}
scheduler.submit("处理数据") {// 处理数据的代码
}
3.优雅关闭:
当所有任务完成后,调度器将在指定的超时后自动关闭,确保不浪费资源。
完整代码
import java.util.concurrent.*
import java.util.concurrent.atomic.AtomicBooleanclass TaskScheduler(private val listener: TaskListener? = null, private val timeout: Long = 5) {private val taskQueue = ConcurrentLinkedQueue<NamedRunnable>()private val isTaskRunning = AtomicBoolean(false)private var executorService: ScheduledExecutorService? = null@Synchronizedfun submit(name: String, task: Runnable) {ensureExecutorService()taskQueue.offer(NamedRunnable(name, task))if (isTaskRunning.compareAndSet(false, true)) {executorService?.submit { processTasks() }}}private fun processTasks() {try {while (taskQueue.isNotEmpty()) {val nextTask = taskQueue.poll()listener?.beforeExecute(nextTask)var exception: Exception? = nulltry {nextTask.run()} catch (e: Exception) {exception = e}listener?.afterExecute(nextTask, exception)}} finally {isTaskRunning.set(false)scheduleShutdown()}}private fun ensureExecutorService() {if (executorService == null || executorService!!.isShutdown) {executorService = Executors.newSingleThreadScheduledExecutor()println("ensureExecutorService newSingleThreadScheduledExecutor")}}private fun scheduleShutdown() {executorService?.schedule({if (taskQueue.isEmpty() && isTaskRunning.compareAndSet(false, true)) {executorService?.shutdown()executorService = nullprintln("scheduleShutdown shutdown")} else {isTaskRunning.set(false) // 确保新任务可以触发执行器重启}}, timeout, TimeUnit.SECONDS)}interface TaskListener {fun beforeExecute(task: NamedRunnable)fun afterExecute(task: NamedRunnable, exception: Exception?)}class NamedRunnable(val name: String, private val task: Runnable) : Runnable {override fun run() {task.run()}}
}
最后
简要概括下优缺点:
- 资源自动管理,超时自动释放资源
- 任务命名,更清晰的了解每个任务执行情况
- 线程安全,不用担心多线程添加任务导致顺序紊乱
优点:
- 灵活性:允许动态添加任务,并根据任务负载需要创建或关闭执行器,从而管理执行器的生命周期。
缺点:
- 单线程限制:当前实现使用单线程执行器,这意味着任务是顺序执行的,而不是并行执行。这可能是CPU密集型任务的瓶颈。
相关文章:
一个用Kotlin编写简易的串行任务调度器
引言 由于项目中有处理大量后台任务并且串行执行的需求,特意写了一个简易的任务调度器,方便监控每个任务执行和异常情况,任务之间互不影响。正如上所述,Kotlin中的TaskScheduler类提供了一个强大的解决方案,用于使用S…...
JavaScript异步编程——11-异常处理方案【万字长文,感谢支持】
异常处理方案 在JS开发中,处理异常包括两步:先抛出异常,然后捕获异常。 为什么要做异常处理 异常处理非常重要,至少有以下几个原因: 防止程序报错甚至停止运行:当代码执行过程中发生错误或异常时&#x…...
python如何做一个服务器fastapi 和flask
用 fastapi 方式的话 from fastapi import FastAPIapp FastAPI()app.get("/api") def index():return "hello world"然后需要安装 uvicorn 并执行下面的命令 uvicorn server:app --port 8000 --reload最终 如果是用 flask 直接写下面的代码 # -*- cod…...
Element-ui el-table组件单选/多选/跨页勾选讲解
文章目录 一、el-table介绍二、el-table单选三、el-table多选四、el-table跨页勾选五、热门文章 一、el-table介绍 el-table 是 Element UI(一个基于 Vue.js 的高质量 UI 组件库)中的一个组件,用于展示表格数据。通过 el-table,你…...
CentOS 安装 SeaweedFS
1. SeaweedFS 介绍 SeaweedFS 是一个简单且高度可扩展的分布式文件系统。有两个目标: to store billions of files! (存储数十亿个文件!)to serve the files fast! (快速提供文件!) Seaweedfs的中心节点(center master)…...
Redis如何避免数据丢失?——AOF
目录 AOF日志 1. 持久化——命令写入到AOF文件 写到用户缓冲区 AOF的触发入口函数——propagate 具体的实现逻辑——feedAppendOnlyFile 从用户缓冲区写入到AOF文件(磁盘) 函数write、fsync、fdatasync Redis的线程池 AOF文件的同步策略 触发的入口函数——…...
xFormers
文章目录 一、关于 xFormers二、安装 xFormers三、基准测试(可选)测试安装 四、使用 xFormers1、Transformers 关键概念2、Repo 地图注意力机制Feed forward mechanismsPositional embeddingResidual pathsInitializations 3、主要特征4、安装故障排除 一…...
LQ杯当时的WP
RC4 32位程序用IDA打开看看 进行反汇编 RC4提示,就是一个加密 在sub_401005函数中找到输出的变量,并且立下断点 动调 Packet 字符串搜索flag 看到是给192.168.11.128发送了cat flag的命令 看到它回传 Base64加密了 解一下密码就可以 CC 密码这…...
数据结构与算法学习笔记三---栈和队列
目录 前言 一、栈 1.栈的表示和实现 1.栈的顺序存储表示和实现 1.C语言实现 2.C实现 2.栈的链式存储表示和实现 1.C语言实现 2.C实现 2.栈的应用 1.数制转换 二、队列 1.栈队列的表示和实现 1.顺序队列的表示和实现 2.链队列的表示和实现 2.循环队列 前言 这篇文…...
web入门——导航栏
本专栏内容代码来自《响应式web(HTML5CSS3Bootstrap)》教材。 导航栏 实现代码: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content&…...
基于梯度流的扩散映射卡尔曼滤波算法的信号预处理matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1 扩散映射(Diffusion Maps) 4.2 卡尔曼滤波 4.3 基于梯度流的扩散映射卡尔曼滤波(GFDMKF) 5.完整程序 1.程序功能描述 基于梯度流的扩散…...
Flutter 中的 ListTile 小部件:全面指南
Flutter 中的 ListTile 小部件:全面指南 在Flutter中,ListTile是一个用于快速创建列表项的组件,它通常用于ListView中,以展示包含文本、图标、开关、滑块等元素的行。ListTile不仅使得界面看起来美观,而且提供了一种简…...
Kubernetes——CNI网络组件
目录 一、Kubernetes三种接口 二、Kubernetes三种网络 三、VLAN与VXLAN 1.VLAN 2.VXLAN 3.区别 3.1作用不同 3.2vxlan支持更多的二层网络 3.3已有的网络路径利用效率更高 3.4防止物理交换机Mac表耗尽 3.5相对VLAN技术,VXLAN技术具有以下优势 四、CNI网…...
对关系型数据库管理系统的介绍
1.数据库的相关介绍 关系型数据库管理系统:(英文简称:RDBMS) 为我们提供了一种存储数据的特定格式,所谓的数据格式就是表, 在数据库中一张表就称为是一种关系. 在关系型数据库中表由两部分组成…...
Nodejs 第七十一章(libuv)
libuv 在Node.js中,libuv是作为其事件循环和异步I/O的核心组件而存在的。Node.js是构建在libuv之上的,它利用libuv来处理底层的异步操作,如文件I/O、网络通信和定时器等。 libuv在Node.js中扮演了以下几个重要角色: 事件循环&a…...
mysql实战题目练习
1、创建和管理数据库 创建一个名为school的数据库。 列出所有的数据库,并确认school数据库已经创建。 如果school数据库已经存在,删除它并重新创建。 mysql> create database school; Query OK, 1 row affected (0.01 sec)mysql> mysql> sh…...
Linux 案例命令使用操作总结
在信息技术日新月异的今天,Linux以其开源、稳定、高效的特性,逐渐成为了众多专业人士的首选操作系统。然而,关于Linux知识的学习,却常常陷入一个误区——许多人认为,掌握Linux就是死记硬背各种命令和参数。这种观念&am…...
图的拓扑序列(DFS2)
reference way:在图里面能延伸的越远,deep越大,说明它能从自己延伸很长到别的节点(别的节点一定有入度),它越可能没有入度。 way:感觉和DFS1差不多,只是从远变成了多。 #include&l…...
2024年小学生古诗文大会备考:吃透历年真题和知识点(持续)
根据往年的安排,2024年小学生古诗文大会预计这个月就将启动。该如何备考2024年小学生古诗文大会呢?根据往期的经验,只要吃透这些真题和背后的知识点,通过上海小学生古诗文大会的初选(初赛)一点问题都没有。…...
SystemC学习使用记录
一、概述 对于复杂的片上系统,在进行RTL编码前,需进行深入的系统级仿真,以确认设计的体系结构是否恰当、总线是否能满足吞吐量和实现性要求以及存储器是否浪费,所进行的这些仿真要求在芯片的仿真模型上运行大量的软件,…...
智能视觉瞄准系统:基于YOLOv8的高效游戏辅助解决方案
智能视觉瞄准系统:基于YOLOv8的高效游戏辅助解决方案 【免费下载链接】RookieAI_yolov8 基于yolov8实现的AI自瞄项目 AI self-aiming project based on yolov8 项目地址: https://gitcode.com/gh_mirrors/ro/RookieAI_yolov8 RookieAI_yolov8是一个基于先进视…...
告别手动重启!用Python+PyAutoGUI写个游戏防崩溃守护脚本(附完整源码)
告别手动重启!用PythonPyAutoGUI打造游戏防崩溃守护脚本 深夜挂机刷副本时突然游戏崩溃,第二天醒来发现角色还在主城发呆?竞技场自动匹配因为断线重连失败而错过赛季奖励?这些问题对于MMO玩家和挂机游戏爱好者来说简直如同噩梦。本…...
实习生,企业的青春代言人
为什么优质的口碑是招募最好的助推器? 在校园招聘中,应届生们不仅看官网的宣传,更看重学长学姐的“真实评价”。一份优质的校招实习经历,不仅能为企业培养出未来的中坚力量,更能通过学生的自发传播,让实习…...
docker启动线程创建异常 pthread_create EPERM | RuntimeError: can‘t start new thread
直接说答案,着急就复制过去使用 docker配置 增加对应权限配置参数即可 --privileged 如果上述不行,docker配置 使用组合方式 --privileged \ --ulimit nproc65535:65535 \ --ulimit nofile65535:65535 \详细解释 下面逐项解释这些 Docker 参数的作用、…...
告别PS!用ImageMagick命令行5分钟搞定100张图片格式批量转换(附Windows/Mac安装避坑)
告别PS!用ImageMagick命令行5分钟搞定100张图片格式批量转换(附Windows/Mac安装避坑) 在数字内容爆炸式增长的今天,图片处理已成为开发者、设计师和内容运营人员的日常刚需。当面对上百张需要统一转换格式、调整尺寸的图片时&…...
Windows字体自由:noMeiryoUI终极指南,轻松自定义系统界面字体
Windows字体自由:noMeiryoUI终极指南,轻松自定义系统界面字体 【免费下载链接】noMeiryoUI No!! MeiryoUI is Windows system font setting tool on Windows 8.1/10/11. 项目地址: https://gitcode.com/gh_mirrors/no/noMeiryoUI 你是否厌倦了Win…...
如何通过Excel MCP Server实现无Excel环境下的自动化表格处理
如何通过Excel MCP Server实现无Excel环境下的自动化表格处理 【免费下载链接】excel-mcp-server A Model Context Protocol server for Excel file manipulation 项目地址: https://gitcode.com/gh_mirrors/ex/excel-mcp-server 你是否曾因没有安装Microsoft Excel而无…...
企业级应用如何通过taotoken统一管理多个大模型api调用与成本
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 企业级应用如何通过Taotoken统一管理多个大模型API调用与成本 对于需要集成多种大语言模型的企业技术团队而言,直接对接…...
Flutter代码混淆实战:五大常见问题与解决方案详解
1. 项目概述:为什么Flutter代码混淆是“必修课”而非“选修课”最近在跟几个独立开发者和中小团队聊Flutter应用上架后的安全状况,发现一个挺普遍的现象:很多人对Flutter的代码混淆要么是“听说过但没做过”,要么是“做了但问题一…...
别再乱配了!Modbus Slave模拟器与iPlat点表地址映射的保姆级避坑指南
Modbus Slave模拟器与工业平台联调实战:从地址映射原理到批量读取优化 工业物联网项目中,Modbus协议作为最常用的数据采集标准,其配置过程看似简单却暗藏玄机。我曾亲眼见过一个资深工程师花了三天时间排查数据采集失败问题,最终发…...
