Java 定时任务技术发展历程

简介: 定时任务是每个业务常见的需求,比如每分钟扫描超时支付的订单,每小时清理一次数据库历史数据,每天统计前一天的数据并生成报表等等。

image.png

定时任务是每个业务常见的需求,比如每分钟扫描超时支付的订单,每小时清理一次数据库历史数据,每天统计前一天的数据并生成报表等等。常见的解决方案有XXL-JOB、Spring-Task等。本篇文章着重于探讨Java 定时任务技术的发展历程。

一、Timer

java.util.Timer 是JDK原生的工具类,用于创建定时任务。

创建 java.util.TimerTask 任务,在 run 方法中实现业务逻辑。通过 java.util.Timer 进行调度,支持按照固定频率或指定Date时刻执行。所有的 TimerTask 是在同一个线程中串行执行,相互影响。也就是说,对于同一个 Timer 里的多个 TimerTask 任务,如果一个 TimerTask 任务在执行中,其它 TimerTask 即使到达执行的时间,也只能排队等待。如果有异常产生,线程将退出,整个定时任务就失败。

   @SneakyThrows
   @Override
   public void run() {
      System.out.println("timerTask1 run ...");
      Thread.sleep(10000);
      System.out.println("timerTask1 finish ...");
   }
};
TimerTask timerTask2 = new TimerTask() {
   @Override
   public void run() {
      System.out.println(System.currentTimeMillis());
      System.out.println("timerTask2 run ...");
   }
};
Timer timer = new Timer();
DateTime date = DateUtil.parse("2022-08-04 15:30:00", DatePattern.NORM_DATETIME_PATTERN);
timer.schedule(timerTask1, date);
timer.schedule(timerTask2, 15000);

二、ScheduledExecutorService

ScheduledExecutorService 是 java.util.concurrent包下基于线程池设计的定时任务解决方案。

每个调度任务都会分配到线程池中的一个线程去执行,解决 Timer 定时器无法并发执行的问题,支持 fixedRate 和 fixedDelay。

   private static final int CORE_SIZE = 5;

   public static void main(String[] args) {
      ScheduledExecutorService executorService = Executors.newScheduledThreadPool(CORE_SIZE);
      // 按照固定频率执行,每隔5秒跑一次
      executorService.scheduleAtFixedRate(() -> System.out.println("hello fixedRate"), 10, 5, TimeUnit.SECONDS);
      // 按照固定延时执行,上次执行完后隔5秒执行下一次
      executorService.scheduleWithFixedDelay(() -> System.out.println("hello fixedDelay"), 10, 5, TimeUnit.SECONDS);
   }
}

三、Spring Task

Spring Task是 SpringBoot提供的轻量级定时任务工具。

我们通过注解可以很方便的配置,支持 cron 表达式、fixedRate、fixedDelay。

@EnableScheduling
public class SpringTaskTest {

   /**
    * 每分钟的第30秒跑一次
    */
   @Scheduled(cron = "30 * * * * ?")
   public void task1() throws InterruptedException {
      System.out.println("hello cron");
   }

   /**
    * 每隔5秒跑一次
    */
   @Scheduled(fixedRate = 5000)
   public void task2() throws InterruptedException {
      System.out.println("hello fixedRate");
   }
   
   /**
    * 上次跑完隔3秒再跑
    */
   @Scheduled(fixedDelay = 3000)
   public void task3() throws InterruptedException {
      System.out.println("hello fixedDelay");
   }
}

四、Quartz

Quartz 是一套轻量级的任务调度框架,由Java编写。

我们只需要定义了 Job(任务),Trigger(触发器)和 Scheduler(调度器),即可实现一个定时调度能力。支持基于数据库的集群模式,本质上还是抢 DB 锁。

image.png

五、XXL-JOB

相关文章
|
2月前
|
Java
死磕-java并发编程技术(二)
死磕-java并发编程技术(二)
|
2月前
|
存储 Java 调度
死磕-java并发编程技术(一)
死磕-java并发编程技术(一)
|
2天前
|
SQL 监控 Java
技术前沿:Java连接池技术的最新发展与应用
本文探讨了Java连接池技术的最新发展与应用,包括高性能与低延迟、智能化管理和监控、扩展性与兼容性等方面。同时,结合最佳实践,介绍了如何选择合适的连接池库、合理配置参数、使用监控工具及优化数据库操作,为开发者提供了一份详尽的技术指南。
17 7
|
4天前
|
移动开发 前端开发 Java
过时的Java技术盘点:避免在这些领域浪费时间
【10月更文挑战第14天】 在快速发展的Java生态系统中,新技术层出不穷,而一些旧技术则逐渐被淘汰。对于Java开发者来说,了解哪些技术已经过时是至关重要的,这可以帮助他们避免在这些领域浪费时间,并将精力集中在更有前景的技术上。本文将盘点一些已经或即将被淘汰的Java技术,为开发者提供指导。
29 7
|
2天前
|
Java 数据库连接 数据库
优化之路:Java连接池技术助力数据库性能飞跃
在Java应用开发中,数据库操作常成为性能瓶颈。频繁的数据库连接建立和断开增加了系统开销,导致性能下降。本文通过问题解答形式,深入探讨Java连接池技术如何通过复用数据库连接,显著减少连接开销,提升系统性能。文章详细介绍了连接池的优势、选择标准、使用方法及优化策略,帮助开发者实现数据库性能的飞跃。
14 4
|
2天前
|
SQL Java 数据库连接
打破瓶颈:利用Java连接池技术提升数据库访问效率
在Java应用中,数据库访问常成为性能瓶颈。连接池技术通过预建立并复用数据库连接,避免了频繁的连接建立和断开,显著提升了数据库访问效率。常见的连接池库包括HikariCP、C3P0和DBCP,它们提供了丰富的配置选项和强大的功能,帮助优化应用性能。
16 2
|
4天前
|
前端开发 Java API
过时Java技术的退役:这些技能你不再需要掌握!
【10月更文挑战第22天】 在快速变化的技术领域,一些曾经流行的Java技术已经逐渐被淘汰,不再适用于现代软件开发。了解这些过时的技术对于新手开发者来说尤为重要,以避免浪费时间和精力学习不再被行业所需的技能。本文将探讨一些已经或即将被淘汰的Java技术,帮助你调整学习路径,专注于那些更有价值的技术。
15 1
|
5天前
|
移动开发 前端开发 JavaScript
java家政系统成品源码的关键特点和技术应用
家政系统成品源码是已开发完成的家政服务管理软件,支持用户注册、登录、管理个人资料,家政人员信息管理,服务项目分类,订单与预约管理,支付集成,评价与反馈,地图定位等功能。适用于各种规模的家政服务公司,采用uniapp、SpringBoot、MySQL等技术栈,确保高效管理和优质用户体验。
|
26天前
|
Java
用java搞定时任务,将hashmap里面的值存到文件里面去
本文介绍了如何使用Java的`Timer`和`TimerTask`类创建一个定时任务,将HashMap中的键值对写入到文本文件中,并提供了完整的示例代码。
31 1
用java搞定时任务,将hashmap里面的值存到文件里面去
|
13天前
|
Java BI 调度
Java Spring的定时任务的配置和使用
遵循上述步骤,你就可以在Spring应用中轻松地配置和使用定时任务,满足各种定时处理需求。
89 1