zl程序教程

您现在的位置是:首页 >  后端

当前栏目

任务调度(二)——jdk自带的Timer 动态修改任务执行计划

JDK执行 修改 动态 任务 计划 自带 timer
2023-09-27 14:29:22 时间

       上一篇博文《任务调度(一)——jdk自带的Timer》中,简单介绍了一下Timer,本文将分享一下如何动态修改Timer制定的计划。


       先上代码:

package com.tgb.ccl.schema.dynamic;

import java.util.Date;

 * 可动态修改的任务

 * @author arron

 * @date 2015年5月9日 下午1:52:15 

 * @version 1.0 

public class DynamicTimerTask extends java.util.TimerTask {

 @Override

 public void run() {

 System.out.println("---------start--------");

 Date d = new Date();

 for(int i=0;i i++){

 try {

 Thread.sleep(1000);

 System.out.println("已执行【"+(i+1)+"】秒钟,at: "+d.toLocaleString());

 } catch (InterruptedException e) {

 e.printStackTrace();

 System.out.println("本次任务调度结束,at: "+new Date().toLocaleString());

 System.out.println("----------------------------------------------");

package com.tgb.ccl.schema.dynamic;

import java.util.Calendar;

import java.util.Date;

import java.util.Timer;

 * 任务调度管理器

 * @author arron

 * @date 2015年5月9日 下午1:57:19

 * @version 1.0

public class DynamicTaskManager {

 private static final long PERIOD = 5 * 1000;// 5秒钟

 * 单例对象

 private static DynamicTaskManager taskManager = null; 

 * 时间调度对象

 private static Timer timer = new Timer();

 * 任务

 private static DynamicTimerTask task = null;

 static {

 taskManager = new DynamicTaskManager();

 public static DynamicTaskManager getInstance(){

 if(taskManager==null){

 taskManager = new DynamicTaskManager();

 return taskManager;

 public DynamicTaskManager() {

 @SuppressWarnings("deprecation")

 public void startTask(Date startTime, long period){

 System.out.println("设置启动时间: "+startTime.toLocaleString());

 //如果当前时间超过了设定时间,会立即执行一次

 task = new DynamicTimerTask();

 timer.schedule(task, startTime,period);


* 取值 Calendar.DAY_OF_MONTH, Calendar.HOUR_OF_DAY, * Calendar.MINUTE,Calendar.SECOND,Calendar.MILLISECOND * @param num * @return public static Date addDay(Date date, int CalendarFlag, int num) { Calendar startDT = Calendar.getInstance(); startDT.setTime(date); startDT.add(CalendarFlag, num); return startDT.getTime(); * 设定时间 * @param hour * @param minute * @param second * @return public static Date bookTime(int hour, int minute, int second) { Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.HOUR_OF_DAY, hour); calendar.set(Calendar.MINUTE, minute); calendar.set(Calendar.SECOND, second); Date date = calendar.getTime(); return date;
public static void main(String[] args) { DynamicTaskManager manager = DynamicTaskManager.getInstance(); //启动任务,会立即执行一次,2s时执行完毕,5s时第二次执行,7s时第二次执行完毕 manager.start(); for(int i=0;i i++){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); //8s时,stop原任务,动态更改启动时间 manager.stop(); System.out.println("当前时间:"+new Date().toLocaleString()); System.out.println("修改原计划,5s后重新执行"); //5s后再启动,即13s时再启动 manager.start(DateUtils.addDay(new Date(), Calendar.SECOND, 5));

       运行结果如下:


       从结果中,我们可以看到,原先的计划是在14:46:40时开始,第二次是在14:46:45,每次执行2s中,也就是说如果不更改任务计划,那么任务将总会在0s或者5s的时候执行。但是我在main方法中,将原来的任务关闭,然后修改了启动时间,当前时间5s后启动新任务。当前时间为14:46:48,5s后执行了新计划。这就完成了任务的动态修改。


       首先说一下,如果关闭任务,stop方法完成了这个功能。要想任务不继续执行,必须将task的状态设置为cancel,然后调用timer的purge方法,将队列里的所有状态为cancel的task移除。这样就算到了执行时间,由于task已经移除,也就不会再执行了。如果使用了timer的cancel()方法,那么会将timer中所有的task全部移除掉。这点要注意一下。


       其实在项目中使用时,要比这个还要简单。直接修改startTask()方法,启动时间和间隔都是从数据库中取就ok了。只要想更改计划时,先配置好启动时间和间隔,然后自己写一个restart的方法,调用clean和startTask方法即可。


       有人问我Timer和Quartz框架的区别。那我就说一下我的理解。Timer毕竟是jdk自带的简易的任务调度工具类,跟Quartz比肯定是鸟枪与大炮的差距。Quartz的配置规则更加强大,更能满足我们的复杂需求,还允许多线程,这是Timer所比不了的。如果你就需要特别简单的任务调度,那么我觉得完全没有必要用Quartz。杀鸡焉用牛刀?!如果你的业务场景比较复杂,比如要求每个月的第4周的最后一个工作日要执行结算工资,如果最后一天是周六,就会向前提一天,在周五执行。这样的场景用Quartz要比Timer简单吧。


       不过具体用什么,还需要看项目。没有什么谁更牛,只有谁更适合。



JVM特点,基础结构与执行周期 虚拟机(Virtual Machine)指通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的完整计算机系统。
180628-动态任务执行框架想法篇 对于后端而言,数据订正可算是非常非常频繁且常见的事情了,常见的有DB、缓存、内存等数据源中的数据订正,对于非应用内存而言,其他有实体或者可以直接通过官方的提供的控制台连接进行修改的数据订正,相对比较简单,而对于应用内存,如果没有应用内通知并处理相关逻辑,多半就只能重启应用来实现刷新内存缓存了
使用 Java 来调度定时任务时,我们经常会使用 Timer 类搞定。Timer 简单易用,其源码阅读起来也非常清晰,本节我们来仔细分析一下 Timer 类,来看看 JDK 源码的编写者是如何实现一个稳定可靠的简单调度器。
龙轩8023 熟悉javaee开发,有多年支付领域的开发经验。关注开源~ httpclientUtil开源项目创建者。https://github.com/Arronlong