当前位置: 首页 > news >正文

【JavaSE】【多线程】定时器

【JavaSE】【多线程】定时器全面详解
—— 从 Timer 到 ScheduledThreadPoolExecutor,再到现代最佳实践

在 Java 多线程开发中,定时任务是非常常见的需求:每隔 5 秒刷新缓存、每天凌晨执行报表、延迟 10 秒发送短信、cron 表达式定时等。本文系统梳理 Java 中定时器的演进与使用方式。

1. Java 定时器演进路线

定时器推出时间是否推荐核心问题适用场景
java.util.Timer+TimerTaskJDK 1.3❌ 不推荐单线程、异常导致整个定时器死亡学习/遗留代码
ScheduledExecutorServiceJDK 1.5✅ 强烈推荐线程池,支持多任务绝大多数业务场景
ScheduledThreadPoolExecutorJDK 1.5✅ 最佳ScheduledExecutorService实现类生产环境首选
Spring@ScheduledSpring✅ 推荐注解驱动,集成简单Spring Boot 项目
Quartz / XXL-JOB / Elastic-Job第三方视情况分布式、持久化、可视化分布式、复杂调度

结论JavaSE 项目首选ScheduledThreadPoolExecutor,Spring 项目优先@Scheduled


2. 经典但已过时的 Timer(了解即可)

Timertimer=newTimer("MyTimer",true);// true 表示守护线程timer.schedule(newTimerTask(){@Overridepublicvoidrun(){System.out.println("定时任务执行:"+newDate());}},1000,2000);// 延迟1秒后,每2秒执行一次

致命缺陷

  • 单线程:所有任务串行执行,一个任务卡住会导致后续全部延误。
  • 异常不捕获:任务抛异常会导致整个 Timer 线程死亡,后续任务全部停止。
  • 不灵活:不支持固定频率(fixedRate)、不支持线程池。

结论:生产环境严禁使用Timer


3. 现代推荐方案:ScheduledExecutorService

3.1 核心接口与常用方法
ScheduledExecutorServicescheduler=Executors.newScheduledThreadPool(10);scheduler.schedule(()->System.out.println("延迟执行"),5,TimeUnit.SECONDS);scheduler.scheduleAtFixedRate(()->System.out.println("固定速率"),2,3,TimeUnit.SECONDS);// 初始延迟2s,之后每3s执行一次scheduler.scheduleWithFixedDelay(()->System.out.println("固定延迟"),2,3,TimeUnit.SECONDS);// 上次执行完后延迟3s再执行

关键区别

  • scheduleAtFixedRate固定速率(以开始时间为基准),适合需要严格周期的任务。
  • scheduleWithFixedDelay固定延迟(以上次结束时间为基准),适合任务执行时间不固定的场景。
3.2 完整生产示例(推荐写法)
publicclassScheduledTaskDemo{privatestaticfinalScheduledExecutorServicescheduler=Executors.newScheduledThreadPool(5,r->{Threadt=newThread(r);t.setDaemon(true);// 守护线程,JVM退出时自动结束t.setName("scheduled-task-");returnt;});publicstaticvoidmain(String[]args){// 1. 延迟一次执行scheduler.schedule(()->System.out.println("5秒后执行"),5,TimeUnit.SECONDS);// 2. 固定速率执行(推荐大多数场景)scheduler.scheduleAtFixedRate(newRunnableTask(),0,10,TimeUnit.SECONDS);// 3. 固定延迟执行scheduler.scheduleWithFixedDelay(newRunnableTask(),0,10,TimeUnit.SECONDS);}staticclassRunnableTaskimplementsRunnable{@Overridepublicvoidrun(){try{System.out.println("任务执行开始:"+newDate());// 模拟业务耗时Thread.sleep(1500);System.out.println("任务执行结束:"+newDate());}catch(Exceptione){e.printStackTrace();}}}// JVM 关闭时优雅关闭线程池static{Runtime.getRuntime().addShutdownHook(newThread(scheduler::shutdown));}}

重要建议

  • 使用自定义 ThreadFactory设置线程名称,便于日志和监控。
  • 设置为守护线程,避免阻止 JVM 正常退出。
  • 捕获异常,防止单个任务失败影响其他任务。
  • 业务量大时合理设置核心线程数(建议 5~50,根据 CPU 核数和任务特性调整)。
  • 程序结束时调用shutdown()shutdownNow()

4. Spring Boot 项目中最推荐的写法(@Scheduled)

@Configuration@EnableSchedulingpublicclassSchedulingConfig{@BeanpublicTaskSchedulertaskScheduler(){ThreadPoolTaskSchedulerscheduler=newThreadPoolTaskScheduler();scheduler.setPoolSize(10);scheduler.setThreadNamePrefix("spring-scheduled-");scheduler.setDaemon(true);scheduler.initialize();returnscheduler;}}// 使用注解@ServicepublicclassReportService{@Scheduled(cron="0 0 2 * * ?")// 每天凌晨 2 点publicvoidgenerateDailyReport(){...}@Scheduled(fixedRate=5000)// 每5秒执行一次(固定速率)publicvoidrefreshCache(){...}@Scheduled(fixedDelay=10000)// 上次执行完后延迟10秒publicvoidcleanTempFiles(){...}}

cron 表达式常用示例

  • 0 0 2 * * ?→ 每天 2:00
  • 0 0/5 * * * ?→ 每 5 分钟
  • 0 15 10 ? * MON-FRI→ 工作日 10:15

5. 高级特性与注意事项

  1. 任务异常处理

    • ScheduledThreadPoolExecutor默认只打印堆栈,不停止调度。
    • 可自定义RejectedExecutionHandlerUncaughtExceptionHandler
  2. 线程池监控

    ThreadPoolExecutorexecutor=(ThreadPoolExecutor)scheduler;executor.getActiveCount();// 当前活跃线程数
  3. 分布式定时任务

    • 单机够用 → ScheduledExecutorService / @Scheduled
    • 分布式 → Quartz + 数据库、XXL-JOB、Elastic-Job、PowerJob 等
  4. 精度问题

    • 定时器精度受 OS 时间片影响(毫秒级),对纳秒级精度需求建议使用 Disruptor + 专用线程。

总结口诀

  • 学习用 Timer(别在生产用)
  • JavaSE 项目用ScheduledThreadPoolExecutor
  • Spring Boot 项目用@Scheduled+TaskScheduler
  • 分布式用专业调度框架

需要我继续补充以下任意内容,随时告诉我:

  • ScheduledThreadPoolExecutor源码核心原理(DelayedWorkQueue)
  • 手写一个支持 cron 的简易定时器
  • Spring Boot + @Scheduled 完整多数据源示例
  • 与 Quartz 的详细对比
  • 定时任务监控(Actuator + Prometheus)

掌握定时器后,你的 Java 多线程能力又上了一个台阶!加油!🚀

http://www.jsqmd.com/news/480632/

相关文章:

  • 2026年杭州心理教练哪家好,费用是怎么收取的 - 工业推荐榜
  • JAVA IO流进阶:字符流与字节流的深度应用
  • 2026酯化态虾青素口碑排行榜,解读老牌酯化态虾青素厂家的实力 - mypinpai
  • QT编程(11):Qt 文本高亮实现代码编辑器
  • 货架厂生产厂家源头工厂选科盛如何,口碑和服务好不好? - 工业品牌热点
  • 深圳江诗丹顿/无锡帝舵/南京浪琴维修哪里好?六大城市高端腕表养护指南 - 时光修表匠
  • 【Python】列表
  • 【开源-Proteus8.9仿真】基于51单片机的超声波测距(HC-SR04+ LCD1602) - 少年
  • Python:基础语法
  • php方案 PHP 实现分布式任务调度
  • 分析钢结构厂房制造厂的性价比,苏东钢结构在全国排名如何 - 工业品牌热点
  • 2026年全国网架钢结构施工靠谱厂家有哪些,产品特色大揭秘 - myqiye
  • php方案 PHP 实现协程调度器
  • Python小白必做的30道基础练习题
  • Python 变量和数据类型
  • 探讨2026年全屋定制MES软件,如何选择合适的产品 - 工业推荐榜
  • 2026年GEO优化靠谱公司有哪些,鸿犀智能口碑出众 - mypinpai
  • 最近爆火的OpenClaw到底是什么?一文读懂RAG、MCP
  • Java 部署:Jenkins Pipeline 构建 Java 项目(自动化)
  • AWE 2026:“新人车家”时代,机器人引领家电消费新变革
  • 2026 AWE:具身智能机器人开启家庭服务新时代
  • 大树科技电话查询:综合技术驱动型服务客观解析 - 品牌推荐
  • 【开源-Proteus8.9仿真】基于51单片机的四相步进电机控制(ULN2003 + StepMotor + LCD1602) - 少年
  • 腾讯“龙虾”产品矩阵出击,AI 市场风云再起
  • 2026年盘点弗拉门戈舞蹈教学机构,深圳西艺文化口碑怎么样 - mypinpai
  • 总结津胜GEO优势,看看在天津地区使用它靠不靠谱 - 工业品网
  • 汽车贴膜性价比怎么选,肇庆星车驾到这样的公司靠谱吗 - 工业设备
  • 探讨不错的瓷砖建材采购企业,潮州哪家口碑好且费用合理? - 工业品牌热点
  • 说说中欧班列货代品牌企业,珠三角地区哪家口碑比较好? - 工业设备
  • 2026年讲讲津胜GEO,其员工素质能满足服务需求吗 - 工业品牌热点