精华内容
下载资源
问答
  • java定时任务测试 继承TimerTask

    千次阅读 2018-08-09 14:44:49
    首先,介绍Java定时器(java.util.Timer)有定时执行计划任务的功能,通过设定定时器的间隔时间,会自动在此间隔时间后执行预先安排好的任务(java.util. TimerTask) 如: 每隔一个小时执行任务 timer.schedule...

     首先,介绍Java定时器(java.util.Timer)有定时执行计划任务的功能,通过设定定时器的间隔时间,会自动在此间隔时间后执行预先安排好的任务(java.util. TimerTask)

    如: 每隔一个小时执行任务 timer.schedule(TimerTask, 0, 60 * 60 * 1000)。

    schedule()方法的

    第一个参数是需要执行的任务,此类的类型为java.util.TimerTask,

    第二个参数为执行任务前等待时间,此处0表示不等待,第三个参数为间隔时间,单位为毫秒。

     /**
      * 定时任务测试类
      * @author admin
      *
      */
    public class TimerScheduleDemo extends TimerTask { 
    	 
    	public TimerScheduleDemo() { 
    	} 
    	 
    	@Override 
    	public void run() { 
    		print();
    	} 
    	 
    	public static void main(String[] args) { 
    		Timer timer = new Timer(); 
    		long delay1 = 1 * 1000; 
    		long period1 = 1000; 
    		// 从现在开始 1*1000 秒钟之后,每隔 1 秒钟执行一次 
    		timer.schedule(new TimerScheduleDemo(), delay1, period1); 
    		/*long delay2 = 2 * 1000; 
    		long period2 = 2000; 
    		// 从现在开始 2 秒钟之后,每隔 2 秒钟执行一次 
    		timer.schedule(new TimerScheduleDemo(), delay2, period2); */
    	} 
    	
    	public static void print(){
    		System.out.println("method start");
    	}
    	
    } 

    但是: 

    由于我们希望当Web工程启动时,定时器能自动开始计时,这样在整个Web工程的生命期里,就会定时的执行任务,因此启动定时器的类不能是一般的类,此处用Servlet的监听器类来启动定时器,通过在配置文件里配置此监听器, 让其在工程启动时自动加载运行,存活期为整个Web工程生命期。

    任务类  主要的业务代码

    /**
     * 定时器任务类:即调度任务类
     * @author admin
     */
    public class DelFileTask extends TimerTask{
    
    
        private static boolean isRunning = false;    
        
        private ServletContext context = null;    
        
        public DelFileTask() {  
            super();  
        }  
          
        public DelFileTask(ServletContext context) {    
            this.context = context;    
        }    
        @Override  
        public void run() {  
              
            if (!isRunning) {  
                   
                context.log("开始执行指定任务");   
                /** 
                 * 自己的业务代码 
                 */  
                  
                isRunning = false;    
                context.log("指定任务执行结束");  
            } else {    
                context.log("上一次任务执行还未结束");    
           }  
        }  
    	 
    }

    这个类 主要是继承 TimerTask并实现它的run 方法

    下面就是监听类了 监听服务器的启动并将任务添加到任务栈

    /**
     * servlet监听器:监听服务启动时执行调度任务
     * @author admin
     *
     */
    public class ContextListener implements ServletContextListener{
    
    	public ContextListener() { 
    		
        }  
          
         private java.util.Timer timer = null;    
           
        /** 
         * 初始化定时器 
         * web 程序运行时候自动加载   
         */  
        @Override  
        public void contextInitialized(ServletContextEvent arg0) {  
              
        	/**
        	 * 设置一个定时器  
        	 */
            timer = new java.util.Timer(true);    
                
            arg0.getServletContext().log("定时器已启动");   
        
            /**
             * 定时器到指定的时间时,执行某个操作(如某个类,或方法)  
             */
            //设置执行时间  
            Calendar calendar =Calendar.getInstance();  
            int year = calendar.get(Calendar.YEAR);  
            int month = calendar.get(Calendar.MONTH);  
            int day =calendar.get(Calendar.DAY_OF_MONTH);//每天  
            //定制每天的16:10:00执行,  
            calendar.set(year, month, day, 16, 10, 00);  
            Date date = calendar.getTime();  
            System.out.println(date);  
            
            int period = 1000;  
            //每天的date时刻执行task,每隔persion 时间重复执行  
            timer.schedule(new DelFileTask(arg0.getServletContext()), date, period);
            
            //在 指定的date时刻执行task, 仅执行一次  
            //timer.schedule(new DelFileTask(arg0.getServletContext()), date);  
              
            arg0.getServletContext().log("已经添加任务调度表");    
              
        }  
      
        /** 
         * 销毁 
         */  
        @Override  
        public void contextDestroyed(ServletContextEvent arg0){  
      
            timer.cancel();  
            arg0.getServletContext().log("定时器销毁");  
        }  
    
    
    }
    

    这个类 主要是设置一个调度器 并让他 按一定的要求去执行任务。

    任务类 监听器类 都实现了 下一步就是在web.xml 配置监听器了 

      <listener>
      	<listener-class>ContextListener</listener-class>
      </listener>

    到了这里   一个简单的定时器基本上实现了 也能跑通了

    展开全文
  • java 定时任务之一 @Scheduled注解(第一种方法)

    万次阅读 多人点赞 2017-12-12 22:09:22
    使用spring @Scheduled注解执行定时任务: 步骤: 1.xmlns 添加: http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd xmlns:task=...

    (本文仅供参考)

    使用spring @Scheduled注解执行定时任务:

     

    步骤:

    1.xmlns 添加

    http://www.springframework.org/schema/task
    http://www.springframework.org/schema/task/spring-task-3.1.xsd
    xmlns:task="http://www.springframework.org/schema/task"

    2.注入:

    <task:annotation-driven/>

    3.注解写在实现类的方法上,实现类上要有组件的注解@Component

    @Scheduled(cron="0/5 * *  * * ? ")   //每5秒执行一次

    运行即可!!!


    关于Cron表达式介绍

    cronExpression定义时间规则,Cron表达式由6或7个空格分隔的时间字段组成:秒 分钟 小时 日期 月份 星期 年(可选)

    字段  允许值  允许的特殊字符 
    秒       0-59     , - * / 
    分       0-59     , - * / 
    小时      0-23     , - * / 
    日期      1-31     , - * ? / L W C 
    月份      1-12     , - * / 
    星期      1-7       , - * ? / L C # 
    年     1970-2099   , - * /

    “*”字符被用来指定所有的值。

    如:

    "*":字符在分钟的字段域里表示“每分钟”。 
    “?”:字符只在日期域和星期域中使用。它被用来指定“非明确的值”。

    当你需要通过在这两个域中的一个来指定一些东西的时候,它是有用的。看下面的例子你就会明白。 
    月份中的日期和星期中的日期这两个元素时互斥的一起应该通过设置一个问号来表明不想设置那个字段。

    “-”:字符被用来指定一个范围。如:“10-12”在小时域意味着“10点、11点、12点”。

    “,”:字符被用来指定另外的值。如:“MON,WED,FRI”在星期域里表示”星期一、星期三、星期五”。

    “/”:字符用于指定增量。

    如:“0/15”在秒域意思是每分钟的0,15,30和45秒。

    “5/15”在分钟域表示每小时的5,20,35和50。

    符号“*”在“/”前面(如:*/10)等价于0在“/”前面(如:0/10)。

    记住一条本质:表达式的每个数值域都是一个有最大值和最小值的集合,如:

    秒域和分钟域的集合是0-59,日期域是1-31,月份域是1-12。字符“/”可以帮助你在每个字符域中取相应的数值。如:“7/6”在月份域的时候只 有当7月的时候才会触发,并不是表示每个6月。

    L是‘last’的省略写法可以表示day-of-month和day-of-week域,但在两个字段中的意思不同,例如day-of- month域中表示一个月的最后一天。如果在day-of-week域表示‘7’或者‘SAT’,如果在day-of-week域中前面加上数字,它表示 一个月的最后几天,例如‘6L’就表示一个月的最后一个星期五。

    字符“W”只允许日期域出现。这个字符用于指定日期的最近工作日。例如:如果你在日期域中写 “15W”,表示:这个月15号最近的工作日。所以,如果15号是周六,则任务会在14号触发。如果15好是周日,则任务会在周一也就是16号触发。如果 是在日期域填写“1W”即使1号是周六,那么任务也只会在下周一,也就是3号触发,“W”字符指定的最近工作日是不能够跨月份的。字符“W”只能配合一个 单独的数值使用,不能够是一个数字段,如:1-15W是错误的。

    “L”和“W”可以在日期域中联合使用,LW表示这个月最后一周的工作日。

    字符“#”只允许在星期域中出现。这个字符用于指定本月的某某天。例如:“6#3”表示本月第三周的星期五(6表示星期五,3表示第三周)。“2#1”表示本月第一周的星期一。“4#5”表示第五周的星期三。

    字符“C”允许在日期域和星期域出现。这个字符依靠一个指定的“日历”。也就是说这个表达式的值依赖于相关的“日历”的计算结果,如果没有“日历” 关联,则等价于所有包含的“日历”。如:日期域是“5C”表示关联“日历”中第一天,或者这个月开始的第一天的后5天。星期域是“1C”表示关联“日历” 中第一天,或者星期的第一天的后1天,也就是周日的后一天(周一)。

    例子如下:

    0 0 10,14,16 * * ? 每天上午10点,下午2点,4点
    0 0/30 9-17 * * ?   朝九晚五工作时间内每半小时
    0 0 12 ? * WED 表示每个星期三中午12点 
    "0 0 12 * * ?" 每天中午12点触发 
    "0 15 10 ? * *" 每天上午10:15触发 
    "0 15 10 * * ?" 每天上午10:15触发 
    "0 15 10 * * ? *" 每天上午10:15触发 
    "0 15 10 * * ? 2005" 2005年的每天上午10:15触发 
    "0 * 14 * * ?" 在每天下午2点到下午2:59期间的每1分钟触发 
    "0 0/5 14 * * ?" 在每天下午2点到下午2:55期间的每5分钟触发 
    "0 0/5 14,18 * * ?" 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发 
    "0 0-5 14 * * ?" 在每天下午2点到下午2:05期间的每1分钟触发 
    "0 10,44 14 ? 3 WED" 每年三月的星期三的下午2:10和2:44触发 
    "0 15 10 ? * MON-FRI" 周一至周五的上午10:15触发 
    "0 15 10 15 * ?" 每月15日上午10:15触发 
    "0 15 10 L * ?" 每月最后一日的上午10:15触发 
    "0 15 10 ? * 6L" 每月的最后一个星期五上午10:15触发 
    "0 15 10 ? * 6L 2002-2005" 2002年至2005年的每月的最后一个星期五上午10:15触发 
    "0 15 10 ? * 6#3" 每月的第三个星期五上午10:15触发

    关于Cron表达式的介绍来源:

    http://blog.csdn.net/supingemail/article/details/22274279

    表达式网站生成:

    http://cron.qqe2.com/  直接点击

     

     

     

    展开全文
  • Java定时任务Schedule实现的4种方式

    万次阅读 多人点赞 2019-02-28 08:38:20
    java实现定时任务 Schedule https://blog.csdn.net/java_2017_csdn/article/details/78060204 2017年09月22日 10:30:52Java_2017_csdn阅读数:3306 java实现定时任务 Schedule 标签:java实现定时任务 Schedule...

    java实现定时任务 Schedule

    https://blog.csdn.net/java_2017_csdn/article/details/78060204

    2017年09月22日 10:30:52 Java_2017_csdn 阅读数:3306

    java实现定时任务 Schedule

    标签: java实现定时任务 Schedulejava实现定时任务java Schedule

    2016-06-07 11:56 16864人阅读 评论(0) 收藏 举报

    分类:

    java(107) 

    目录(?)[+]

    1.java定时任务可以借助 java.util.Timer 来实现

    [java] view plain copy

    1. import java.util.Calendar;  
    2. import java.util.Date;  
    3. import java.util.Timer;  
    4. import java.util.TimerTask;  
    5.   
    6. public class Test {  
    7.     public static void main(String[] args) {  
    8.         //timer1();  
    9.         timer2();  
    10.         //timer3();  
    11.         //timer4();  
    12.     }  
    13.   
    14.     // 第一种方法:设定指定任务task在指定时间time执行 schedule(TimerTask task, Date time)  
    15.     public static void timer1() {  
    16.         Timer timer = new Timer();  
    17.         timer.schedule(new TimerTask() {  
    18.             public void run() {  
    19.                 System.out.println("-------设定要指定任务--------");  
    20.             }  
    21.         }, 2000);// 设定指定的时间time,此处为2000毫秒  
    22.     }  
    23.   
    24.     // 第二种方法:设定指定任务task在指定延迟delay后进行固定延迟peroid的执行  
    25.     // schedule(TimerTask task, long delay, long period)  
    26.     public static void timer2() {  
    27.         Timer timer = new Timer();  
    28.         timer.schedule(new TimerTask() {  
    29.             public void run() {  
    30.                 System.out.println("-------设定要指定任务--------");  
    31.             }  
    32.         }, 1000, 1000);  
    33.     }  
    34.   
    35.     // 第三种方法:设定指定任务task在指定延迟delay后进行固定频率peroid的执行。  
    36.     // scheduleAtFixedRate(TimerTask task, long delay, long period)  
    37.     public static void timer3() {  
    38.         Timer timer = new Timer();  
    39.         timer.scheduleAtFixedRate(new TimerTask() {  
    40.             public void run() {  
    41.                 System.out.println("-------设定要指定任务--------");  
    42.             }  
    43.         }, 1000, 2000);  
    44.     }  
    45.      
    46.     // 第四种方法:安排指定的任务task在指定的时间firstTime开始进行重复的固定速率period执行.  
    47.     // Timer.scheduleAtFixedRate(TimerTask task,Date firstTime,long period)  
    48.     public static void timer4() {  
    49.         Calendar calendar = Calendar.getInstance();  
    50.         calendar.set(Calendar.HOUR_OF_DAY, 12); // 控制时  
    51.         calendar.set(Calendar.MINUTE, 0);       // 控制分  
    52.         calendar.set(Calendar.SECOND, 0);       // 控制秒  
    53.   
    54.         Date time = calendar.getTime();         // 得出执行任务的时间,此处为今天的12:00:00  
    55.   
    56.         Timer timer = new Timer();  
    57.         timer.scheduleAtFixedRate(new TimerTask() {  
    58.             public void run() {  
    59.                 System.out.println("-------设定要指定任务--------");  
    60.             }  
    61.         }, time, 1000 * 60 * 60 * 24);// 这里设定将延时每天固定执行  
    62.     }  
    63. }  

     

    2. Java定时任务可以用线程的等待来实现

     

    [java] view plain copy

    1. /**  
    2.  * 普通thread  
    3.  * 这是最常见的,创建一个thread,然后让它在while循环里一直运行着,  
    4.  * 通过sleep方法来达到定时任务的效果。这样可以快速简单的实现,代码如下:  
    5.  * @author GT  
    6.  *  
    7.  */    
    8. public class Task1 {    
    9.     public static void main(String[] args) {    
    10.         // run in a second    
    11.         final long timeInterval = 1000;    
    12.         Runnable runnable = new Runnable() {    
    13.             public void run() {    
    14.                 while (true) {    
    15.                     // ------- code for task to run    
    16.                     System.out.println("Hello !!");    
    17.                     // ------- ends here    
    18.                     try {    
    19.                         Thread.sleep(timeInterval);    
    20.                     } catch (InterruptedException e) {    
    21.                         e.printStackTrace();    
    22.                     }    
    23.                 }    
    24.             }    
    25.         };    
    26.         Thread thread = new Thread(runnable);    
    27.         thread.start();    
    28.     }    
    29. }   

     

    3.Java可以用java.util.concurrent.ScheduledExecutorService 来实现定时任务

     

    [java] view plain copy

    1. import java.util.concurrent.Executors;    
    2. import java.util.concurrent.ScheduledExecutorService;    
    3. import java.util.concurrent.TimeUnit;    
    4.     
    5. /**  
    6.  *   
    7.  *   
    8.  * ScheduledExecutorService是从Java SE5的java.util.concurrent里,做为并发工具类被引进的,这是最理想的定时任务实现方式。   
    9.  * 相比于上两个方法,它有以下好处:  
    10.  * 1>相比于Timer的单线程,它是通过线程池的方式来执行任务的   
    11.  * 2>可以很灵活的去设定第一次执行任务delay时间  
    12.  * 3>提供了良好的约定,以便设定执行的时间间隔  
    13.  *   
    14.  * 下面是实现代码,我们通过ScheduledExecutorService#scheduleAtFixedRate展示这个例子,通过代码里参数的控制,首次执行加了delay时间。  
    15.  *   
    16.  *   
    17.  * @author GT  
    18.  *   
    19.  */    
    20. public class Task3 {    
    21.     public static void main(String[] args) {    
    22.         Runnable runnable = new Runnable() {    
    23.             public void run() {    
    24.                 // task to run goes here    
    25.                 System.out.println("Hello !!");    
    26.             }    
    27.         };    
    28.         ScheduledExecutorService service = Executors    
    29.                 .newSingleThreadScheduledExecutor();    
    30.         // 第二个参数为首次执行的延时时间,第三个参数为定时执行的间隔时间    
    31.         service.scheduleAtFixedRate(runnable, 10, 1, TimeUnit.SECONDS);    
    32.     }    
    33. }    

     

    4. 定时任务之-Quartz使用篇

    Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的日程序表。Jobs可以做成标准的Java组件或 EJBs。

     

    CronTrigger配置格式:
    格式: [秒] [分] [小时] [日] [月] [周] [年]

    序号 说明 是否必填 允许填写的值 允许的通配符
    1 0-59 , - * /
    2 0-59 , - * /
    3 小时 0-23 , - * /
    4 1-31 , - * ? / L W
    5 1-12 or JAN-DEC , - * /
    6 1-7 or SUN-SAT , - * ? / L #
    7 empty 或 1970-2099 , - * /

     

    通配符说明:
    * 表示所有值. 例如:在分的字段上设置 "*",表示每一分钟都会触发。
    ? 表示不指定值。使用的场景为不需要关心当前设置这个字段的值。例如:要在每月的10号触发一个操作,但不关心是周几,所以需要周位置的那个字段设置为"?" 具体设置为 0 0 0 10* ?
    - 表示区间。例如 在小时上设置 "10-12",表示 10,11,12点都会触发。
    , 表示指定多个值,例如在周字段上设置 "MON,WED,FRI" 表示周一,周三和周五触发
    / 用于递增触发。如在秒上面设置"5/15" 表示从5秒开始,每增15秒触发(5,20,35,50)。在月字段上设置'1/3'所示每月1号开始,每隔三天触发一次。
    L 表示最后的意思。在日字段设置上,表示当月的最后一天(依据当前月份,如果是二月还会依据是否是润年[leap]), 在周字段上表示星期六,相当于"7"或"SAT"。如果在"L"前加上数字,则表示该数据的最后一个。例如在周字段上设置"6L"这样的格式,则表示“本月最后一个星期五"
    W 表示离指定日期的最近那个工作日(周一至周五). 例如在日字段上设置"15W",表示离每月15号最近的那个工作日触发。如果15号正好是周六,则找最近的周五(14号)触发, 如果15号是周未,则找最近的下周一(16号)触发.如果15号正好在工作日(周一至周五),则就在该天触发。如果指定格式为 "1W",它则表示每月1号往后最近的工作日触发。如果1号正是周六,则将在3号下周一触发。(注,"W"前只能设置具体的数字,不允许区间"-").

    小提示

    'L'和 'W'可以一组合使用。如果在日字段上设置"LW",则表示在本月的最后一个工作日触发(一般指发工资 ) 

    # 序号(表示每月的第几个周几),例如在周字段上设置"6#3"表示在每月的第三个周六.注意如果指定"#5",正好第五周没有周六,则不会触发该配置(用在母亲节和父亲节再合适不过了)

    小提示 周字段的设置,若使用英文字母是不区分大小写的 MON 与mon相同.

     

    常用示例:

    0 0 12 * * ? 每天12点触发
    0 15 10 ? * * 每天10点15分触发
    0 15 10 * * ? 每天10点15分触发
    0 15 10 * * ? * 每天10点15分触发
    0 15 10 * * ? 2005 2005年每天10点15分触发
    0 * 14 * * ? 每天下午的 2点到2点59分每分触发
    0 0/5 14 * * ? 每天下午的 2点到2点59分(整点开始,每隔5分触发)
    0 0/5 14,18 * * ? 每天下午的 2点到2点59分(整点开始,每隔5分触发)每天下午的 18点到18点59分(整点开始,每隔5分触发)
    0 0-5 14 * * ? 每天下午的 2点到2点05分每分触发
    0 10,44 14 ? 3 WED 3月分每周三下午的 2点10分和2点44分触发
    0 15 10 ? * MON-FRI 从周一到周五每天上午的10点15分触发
    0 15 10 15 * ? 每月15号上午10点15分触发
    0 15 10 L * ? 每月最后一天的10点15分触发
    0 15 10 ? * 6L 每月最后一周的星期五的10点15分触发
    0 15 10 ? * 6L 2002-2005 从2002年到2005年每月最后一周的星期五的10点15分触发
    0 15 10 ? * 6#3 每月的第三周的星期五开始触发
    0 0 12 1/5 * ? 每月的第一个中午开始每隔5天触发一次
    0 11 11 11 11 ? 每年的11月11号 11点11分触发(光棍节)

    经过封装的管理类:


    [java] view plain copy

    1. import java.text.ParseException;    
    2.     
    3. import org.quartz.CronTrigger;    
    4. import org.quartz.JobDetail;    
    5. import org.quartz.Scheduler;    
    6. import org.quartz.SchedulerException;    
    7. import org.quartz.SchedulerFactory;    
    8. import org.quartz.impl.StdSchedulerFactory;    
    9.     
    10. /**  
    11.  * 定时任务管理类  
    12.  *  
    13.  */    
    14. public class QuartzManager {    
    15.     private static SchedulerFactory gSchedulerFactory = new StdSchedulerFactory();    
    16.     private static String JOB_GROUP_NAME = "EXTJWEB_JOBGROUP_NAME";    
    17.     private static String TRIGGER_GROUP_NAME = "EXTJWEB_TRIGGERGROUP_NAME";    
    18.     
    19.     /**  
    20.      * 添加一个定时任务,使用默认的任务组名,触发器名,触发器组名  
    21.      *  
    22.      * @param jobName  
    23.      *            任务名  
    24.      * @param jobClass  
    25.      *            任务  
    26.      * @param time  
    27.      *            时间设置,参考quartz说明文档  
    28.      * @throws SchedulerException  
    29.      * @throws ParseException  
    30.      */    
    31.     public static void addJob(String jobName, String jobClass, String time) {    
    32.         try {    
    33.             Scheduler sched = gSchedulerFactory.getScheduler();    
    34.             JobDetail jobDetail = new JobDetail(jobName, JOB_GROUP_NAME, Class.forName(jobClass));// 任务名,任务组,任务执行类    
    35.             // 触发器    
    36.             CronTrigger trigger = new CronTrigger(jobName, TRIGGER_GROUP_NAME);// 触发器名,触发器组    
    37.             trigger.setCronExpression(time);// 触发器时间设定    
    38.             sched.scheduleJob(jobDetail, trigger);    
    39.             // 启动    
    40.             if (!sched.isShutdown()){    
    41.                 sched.start();    
    42.             }    
    43.         } catch (Exception e) {    
    44.             e.printStackTrace();    
    45.             throw new RuntimeException(e);    
    46.         }    
    47.     }    
    48.     
    49.     /**  
    50.      * 添加一个定时任务  
    51.      *  
    52.      * @param jobName  
    53.      *            任务名  
    54.      * @param jobGroupName  
    55.      *            任务组名  
    56.      * @param triggerName  
    57.      *            触发器名  
    58.      * @param triggerGroupName  
    59.      *            触发器组名  
    60.      * @param jobClass  
    61.      *            任务  
    62.      * @param time  
    63.      *            时间设置,参考quartz说明文档  
    64.      * @throws SchedulerException  
    65.      * @throws ParseException  
    66.      */    
    67.     public static void addJob(String jobName, String jobGroupName,    
    68.             String triggerName, String triggerGroupName, String jobClass, String time){    
    69.         try {    
    70.             Scheduler sched = gSchedulerFactory.getScheduler();    
    71.             JobDetail jobDetail = new JobDetail(jobName, jobGroupName, Class.forName(jobClass));// 任务名,任务组,任务执行类    
    72.             // 触发器    
    73.             CronTrigger trigger = new CronTrigger(triggerName, triggerGroupName);// 触发器名,触发器组    
    74.             trigger.setCronExpression(time);// 触发器时间设定    
    75.             sched.scheduleJob(jobDetail, trigger);    
    76.         } catch (Exception e) {    
    77.             e.printStackTrace();    
    78.             throw new RuntimeException(e);    
    79.         }    
    80.     }    
    81.     
    82.     /**  
    83.      * 修改一个任务的触发时间(使用默认的任务组名,触发器名,触发器组名)  
    84.      *  
    85.      * @param jobName  
    86.      * @param time  
    87.      */    
    88.     public static void modifyJobTime(String jobName, String time) {    
    89.         try {    
    90.             Scheduler sched = gSchedulerFactory.getScheduler();    
    91.             CronTrigger trigger = (CronTrigger) sched.getTrigger(jobName, TRIGGER_GROUP_NAME);    
    92.             if(trigger == null) {    
    93.                 return;    
    94.             }    
    95.             String oldTime = trigger.getCronExpression();    
    96.             if (!oldTime.equalsIgnoreCase(time)) {    
    97.                 JobDetail jobDetail = sched.getJobDetail(jobName, JOB_GROUP_NAME);    
    98.                 Class objJobClass = jobDetail.getJobClass();    
    99.                 String jobClass = objJobClass.getName();    
    100.                 removeJob(jobName);    
    101.     
    102.                 addJob(jobName, jobClass, time);    
    103.             }    
    104.         } catch (Exception e) {    
    105.             e.printStackTrace();    
    106.             throw new RuntimeException(e);    
    107.         }    
    108.     }    
    109.     
    110.     /**  
    111.      * 修改一个任务的触发时间  
    112.      *  
    113.      * @param triggerName  
    114.      * @param triggerGroupName  
    115.      * @param time  
    116.      */    
    117.     public static void modifyJobTime(String triggerName,    
    118.             String triggerGroupName, String time) {    
    119.         try {    
    120.             Scheduler sched = gSchedulerFactory.getScheduler();    
    121.             CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerName, triggerGroupName);    
    122.             if(trigger == null) {    
    123.                 return;    
    124.             }    
    125.             String oldTime = trigger.getCronExpression();    
    126.             if (!oldTime.equalsIgnoreCase(time)) {    
    127.                 CronTrigger ct = (CronTrigger) trigger;    
    128.                 // 修改时间    
    129.                 ct.setCronExpression(time);    
    130.                 // 重启触发器    
    131.                 sched.resumeTrigger(triggerName, triggerGroupName);    
    132.             }    
    133.         } catch (Exception e) {    
    134.             e.printStackTrace();    
    135.             throw new RuntimeException(e);    
    136.         }    
    137.     }    
    138.     
    139.     /**  
    140.      * 移除一个任务(使用默认的任务组名,触发器名,触发器组名)  
    141.      *  
    142.      * @param jobName  
    143.      */    
    144.     public static void removeJob(String jobName) {    
    145.         try {    
    146.             Scheduler sched = gSchedulerFactory.getScheduler();    
    147.             sched.pauseTrigger(jobName, TRIGGER_GROUP_NAME);// 停止触发器    
    148.             sched.unscheduleJob(jobName, TRIGGER_GROUP_NAME);// 移除触发器    
    149.             sched.deleteJob(jobName, JOB_GROUP_NAME);// 删除任务    
    150.         } catch (Exception e) {    
    151.             e.printStackTrace();    
    152.             throw new RuntimeException(e);    
    153.         }    
    154.     }    
    155.     
    156.     /**  
    157.      * 移除一个任务  
    158.      *  
    159.      * @param jobName  
    160.      * @param jobGroupName  
    161.      * @param triggerName  
    162.      * @param triggerGroupName  
    163.      */    
    164.     public static void removeJob(String jobName, String jobGroupName,    
    165.             String triggerName, String triggerGroupName) {    
    166.         try {    
    167.             Scheduler sched = gSchedulerFactory.getScheduler();    
    168.             sched.pauseTrigger(triggerName, triggerGroupName);// 停止触发器    
    169.             sched.unscheduleJob(triggerName, triggerGroupName);// 移除触发器    
    170.             sched.deleteJob(jobName, jobGroupName);// 删除任务    
    171.         } catch (Exception e) {    
    172.             e.printStackTrace();    
    173.             throw new RuntimeException(e);    
    174.         }    
    175.     }    
    176.     
    177.     /**  
    178.      * 启动所有定时任务  
    179.      */    
    180.     public static void startJobs() {    
    181.         try {    
    182.             Scheduler sched = gSchedulerFactory.getScheduler();    
    183.             sched.start();    
    184.         } catch (Exception e) {    
    185.             e.printStackTrace();    
    186.             throw new RuntimeException(e);    
    187.         }    
    188.     }    
    189.     
    190.     /**  
    191.      * 关闭所有定时任务  
    192.      */    
    193.     public static void shutdownJobs() {    
    194.         try {    
    195.             Scheduler sched = gSchedulerFactory.getScheduler();    
    196.             if(!sched.isShutdown()) {    
    197.                 sched.shutdown();    
    198.             }    
    199.         } catch (Exception e) {    
    200.             e.printStackTrace();    
    201.             throw new RuntimeException(e);    
    202.         }    
    203.     }    
    204. }    


    简单实现Schedule的Quartz的例子

     

     第一步:引包

      要使用Quartz,必须要引入以下这几个包:

      1、log4j-1.2.16

      2、quartz-2.1.7

      3、slf4j-api-1.6.1.jar

      4、slf4j-log4j12-1.6.1.jar

      这些包都在下载的Quartz包里面包含着,因此没有必要为寻找这几个包而头疼。

      第二步:创建要被定执行的任务类

      这一步也很简单,只需要创建一个实现了org.quartz.Job接口的类,并实现这个接口的唯一一个方法execute(JobExecutionContext arg0) throws JobExecutionException即可。如:

    [java] view plain copy

    1. import java.text.SimpleDateFormat;   
    2.    
    3. import java.util.Date;   
    4.    
    5. import org.quartz.Job;   
    6. import org.quartz.JobExecutionContext;   
    7. import org.quartz.JobExecutionException;   
    8.    
    9. public class myJob implements Job {   
    10.    
    11.     @Override   
    12.     public void execute(JobExecutionContext arg0) throws JobExecutionException {   
    13.         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");   
    14.         System.out.println(sdf.format(new Date()));   
    15.     }   
    16.    
    17. }   


     第三步:创建任务调度,并执行

     

    [java] view plain copy

    1. import java.text.SimpleDateFormat;  
    2. import java.util.Date;  
    3.   
    4. import org.quartz.CronTrigger;  
    5. import org.quartz.JobDetail;  
    6. import org.quartz.Scheduler;  
    7. import org.quartz.SchedulerFactory;  
    8. import org.quartz.impl.StdSchedulerFactory;  
    9.   
    10. public class Test {  
    11.     public void go() throws Exception {  
    12.         // 首先,必需要取得一个Scheduler的引用  
    13.         SchedulerFactory sf = new StdSchedulerFactory();  
    14.         Scheduler sched = sf.getScheduler();  
    15.         String time="0 51 11 ? * *";  
    16.         // jobs可以在scheduled的sched.start()方法前被调用  
    17.   
    18.         // job 1将每隔20秒执行一次  
    19.         JobDetail job = new JobDetail("job1", "group1", myJob.class);  
    20.         CronTrigger trigger = new CronTrigger("trigger1", "group1");  
    21.         trigger.setCronExpression(time);  
    22.         Date ft = sched.scheduleJob(job, trigger);  
    23.         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");  
    24.         System.out.println(  
    25.                 job.getKey() + " 已被安排执行于: " + sdf.format(ft) + ",并且以如下重复规则重复执行: " + trigger.getCronExpression());  
    26.   
    27.         // job 2将每2分钟执行一次(在该分钟的第15秒)  
    28.         job = new JobDetail("job2", "group1",myJob.class);  
    29.         trigger = new CronTrigger("trigger2", "group1");  
    30.         trigger.setCronExpression(time);  
    31.         ft = sched.scheduleJob(job, trigger);  
    32.         System.out.println(  
    33.                 job.getKey() + " 已被安排执行于: " + sdf.format(ft) + ",并且以如下重复规则重复执行: " + trigger.getCronExpression());  
    34.   
    35.         // 开始执行,start()方法被调用后,计时器就开始工作,计时调度中允许放入N个Job  
    36.         sched.start();  
    37.         try {  
    38.             // 主线程等待一分钟  
    39.             Thread.sleep(60L * 1000L);  
    40.         } catch (Exception e) {  
    41.         }  
    42.         // 关闭定时调度,定时器不再工作  
    43.         sched.shutdown(true);  
    44.     }  
    45.   
    46.     public static void main(String[] args) throws Exception {  
    47.   
    48.         Test test = new Test();  
    49.         test.go();  
    50.     }  
    51.   
    52. }  

     

    展开全文
  • java定时任务

    千次阅读 2019-05-30 15:25:04
    java中一个完整定时任务需要由Timer、TimerTask两个类来配合完成。 API中是这样定义他们的,Timer:一种工具,线程用其安排以后在后台线程中执行的任务。可安排任务执行一次,或者定期重复执行。由TimerTask:...

    转自:https://blog.csdn.net/strivenoend/article/details/80640031
    一、简介
    在java中一个完整定时任务需要由Timer、TimerTask两个类来配合完成。 API中是这样定义他们的,Timer:一种工具,线程用其安排以后在后台线程中执行的任务。可安排任务执行一次,或者定期重复执行。由TimerTask:Timer 安排为一次执行或重复执行的任务。我们可以这样理解Timer是一种定时器工具,用来在一个后台线程计划执行指定任务,而TimerTask一个抽象类,它的子类代表一个可以被Timer计划的任务。

    Timer类
    在工具类Timer中,提供了四个构造方法,每个构造方法都启动了计时器线程,同时Timer类可以保证多个线程可以共享单个Timer对象而无需进行外部同步,所以Timer类是线程安全的。但是由于每一个Timer对象对应的是单个后台线程,用于顺序执行所有的计时器任务,一般情况下我们的线程任务执行所消耗的时间应该非常短,但是由于特殊情况导致某个定时器任务执行的时间太长,那么他就会“独占”计时器的任务执行线程,其后的所有线程都必须等待它执行完,这就会延迟后续任务的执行,使这些任务堆积在一起,具体情况我们后面分析。

      当程序初始化完成Timer后,定时任务就会按照我们设定的时间去执行,Timer提供了schedule方法,该方法有多中重载方式来适应不同的情况,如下:
    
      schedule(TimerTask task, Date time):安排在指定的时间执行指定的任务。
    
      schedule(TimerTask task, Date firstTime, long period) :安排指定的任务在指定的时间开始进行重复的固定延迟执行。
    
      schedule(TimerTask task, long delay) :安排在指定延迟后执行指定的任务。
    
      schedule(TimerTask task, long delay, long period) :安排指定的任务从指定的延迟后开始进行重复的固定延迟执行。
    
      同时也重载了scheduleAtFixedRate方法,scheduleAtFixedRate方法与schedule相同,只不过他们的侧重点不同,区别后面分析。
    
      scheduleAtFixedRate(TimerTask task, Date firstTime, long period):安排指定的任务在指定的时间开始进行重复的固定速率执行。
    
      scheduleAtFixedRate(TimerTask task, long delay, long period):安排指定的任务在指定的延迟后开始进行重复的固定速率执行。
    

    TimerTask
    TimerTask类是一个抽象类,由Timer 安排为一次执行或重复执行的任务。它有一个抽象方法run()方法,该方法用于执行相应计时器任务要执行的操作。因此每一个具体的任务类都必须继承TimerTask,然后重写run()方法。

      另外它还有两个非抽象的方法:
    
      boolean cancel():取消此计时器任务。
    
      long scheduledExecutionTime():返回此任务最近实际执行的安排执行时间。
    

    二、实例
    2.1、指定延迟时间执行定时任务
    [java] view plain copy
    public class TimerTest01 {
    Timer timer;
    public TimerTest01(int time){
    timer = new Timer();
    timer.schedule(new TimerTaskTest01(), time * 1000);
    }

    public static void main(String[] args) {  
        System.out.println("timer begin....");  
        new TimerTest01(3);  
    }  
    

    }

    public class TimerTaskTest01 extends TimerTask{

    public void run() {  
        System.out.println("Time's up!!!!");  
    }  
    

    }
    public class TimerTest01 {
    Timer timer;
    public TimerTest01(int time){
    timer = new Timer();
    timer.schedule(new TimerTaskTest01(), time * 1000);
    }

    public static void main(String[] args) {
        System.out.println("timer begin....");
        new TimerTest01(3);
    }
    

    }

    public class TimerTaskTest01 extends TimerTask{

    public void run() {
        System.out.println("Time's up!!!!");
    }
    

    }

      运行结果:
    

    [java] view plain copy
    首先打印:timer begin…

    3秒后打印:Time’s up!!!
    首先打印:timer begin…

    3秒后打印:Time’s up!!!

      2.2、在指定时间执行定时任务
    

    [java] view plain copy
    public class TimerTest02 {
    Timer timer;

    public TimerTest02(){  
        Date time = getTime();  
        System.out.println("指定时间time=" + time);  
        timer = new Timer();  
        timer.schedule(new TimerTaskTest02(), time);  
    }  
      
    public Date getTime(){  
        Calendar calendar = Calendar.getInstance();  
        calendar.set(Calendar.HOUR_OF_DAY, 11);  
        calendar.set(Calendar.MINUTE, 39);  
        calendar.set(Calendar.SECOND, 00);  
        Date time = calendar.getTime();  
          
        return time;  
    }  
      
    public static void main(String[] args) {  
        new TimerTest02();  
    }  
    

    }

    public class TimerTaskTest02 extends TimerTask{

    @Override  
    public void run() {  
        System.out.println("指定时间执行线程任务...");  
    }  
    

    }
    public class TimerTest02 {
    Timer timer;

    public TimerTest02(){
        Date time = getTime();
        System.out.println("指定时间time=" + time);
        timer = new Timer();
        timer.schedule(new TimerTaskTest02(), time);
    }
    
    public Date getTime(){
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 11);
        calendar.set(Calendar.MINUTE, 39);
        calendar.set(Calendar.SECOND, 00);
        Date time = calendar.getTime();
        
        return time;
    }
    
    public static void main(String[] args) {
        new TimerTest02();
    }
    

    }

    public class TimerTaskTest02 extends TimerTask{

    @Override
    public void run() {
        System.out.println("指定时间执行线程任务...");
    }
    

    }

      当时间到达11:39:00时就会执行该线程任务,当然大于该时间也会执行!!执行结果为:
    

    [java] view plain copy
    指定时间time=Tue Jun 10 11:39:00 CST 2014
    指定时间执行线程任务…
    指定时间time=Tue Jun 10 11:39:00 CST 2014
    指定时间执行线程任务…
    2.3、在延迟指定时间后以指定的间隔时间循环执行定时任务
    [java] view plain copy
    public class TimerTest03 {
    Timer timer;

    public TimerTest03(){  
        timer = new Timer();  
        timer.schedule(new TimerTaskTest03(), 1000, 2000);  
    }  
      
    public static void main(String[] args) {  
        new TimerTest03();  
    }  
    

    }

    public class TimerTaskTest03 extends TimerTask{

    @Override  
    public void run() {  
        Date date = new Date(this.scheduledExecutionTime());  
        System.out.println("本次执行该线程的时间为:" + date);  
    }  
    

    }
    public class TimerTest03 {
    Timer timer;

    public TimerTest03(){
        timer = new Timer();
        timer.schedule(new TimerTaskTest03(), 1000, 2000);
    }
    
    public static void main(String[] args) {
        new TimerTest03();
    }
    

    }

    public class TimerTaskTest03 extends TimerTask{

    @Override
    public void run() {
        Date date = new Date(this.scheduledExecutionTime());
        System.out.println("本次执行该线程的时间为:" + date);
    }
    

    }

      运行结果:
    

    [java] view plain copy
    本次执行该线程的时间为:Tue Jun 10 21:19:47 CST 2014
    本次执行该线程的时间为:Tue Jun 10 21:19:49 CST 2014
    本次执行该线程的时间为:Tue Jun 10 21:19:51 CST 2014
    本次执行该线程的时间为:Tue Jun 10 21:19:53 CST 2014
    本次执行该线程的时间为:Tue Jun 10 21:19:55 CST 2014
    本次执行该线程的时间为:Tue Jun 10 21:19:57 CST 2014

    本次执行该线程的时间为:Tue Jun 10 21:19:47 CST 2014
    本次执行该线程的时间为:Tue Jun 10 21:19:49 CST 2014
    本次执行该线程的时间为:Tue Jun 10 21:19:51 CST 2014
    本次执行该线程的时间为:Tue Jun 10 21:19:53 CST 2014
    本次执行该线程的时间为:Tue Jun 10 21:19:55 CST 2014
    本次执行该线程的时间为:Tue Jun 10 21:19:57 CST 2014

    对于这个线程任务,如果我们不将该任务停止,他会一直运行下去。

      对于上面三个实例,LZ只是简单的演示了一下,同时也没有讲解scheduleAtFixedRate方法的例子,其实该方法与schedule方法一样!
    
      2.4、分析schedule和scheduleAtFixedRate
      1、schedule(TimerTask task, Date time)、schedule(TimerTask task, long delay)
    
      对于这两个方法而言,如果指定的计划执行时间scheduledExecutionTime<= systemCurrentTime,则task会被立即执行。scheduledExecutionTime不会因为某一个task的过度执行而改变。
    
      2、schedule(TimerTask task, Date firstTime, long period)、schedule(TimerTask task, long delay, long period)
    
      这两个方法与上面两个就有点儿不同的,前面提过Timer的计时器任务会因为前一个任务执行时间较长而延时。在这两个方法中,每一次执行的task的计划时间会随着前一个task的实际时间而发生改变,也就是scheduledExecutionTime(n+1)=realExecutionTime(n)+periodTime。也就是说如果第n个task由于某种情况导致这次的执行时间过程,最后导致systemCurrentTime>= scheduledExecutionTime(n+1),这是第n+1个task并不会因为到时了而执行,他会等待第n个task执行完之后再执行,那么这样势必会导致n+2个的执行实现scheduledExecutionTime放生改变即scheduledExecutionTime(n+2) = realExecutionTime(n+1)+periodTime。所以这两个方法更加注重保存间隔时间的稳定。
    
      3、scheduleAtFixedRate(TimerTask task, Date firstTime, long period)、scheduleAtFixedRate(TimerTask task, long delay, long period)
    
      在前面也提过scheduleAtFixedRate与schedule方法的侧重点不同,schedule方法侧重保存间隔时间的稳定,而scheduleAtFixedRate方法更加侧重于保持执行频率的稳定。为什么这么说,原因如下。在schedule方法中会因为前一个任务的延迟而导致其后面的定时任务延时,而scheduleAtFixedRate方法则不会,如果第n个task执行时间过长导致systemCurrentTime>= scheduledExecutionTime(n+1),则不会做任何等待他会立即执行第n+1个task,所以scheduleAtFixedRate方法执行时间的计算方法不同于schedule,而是scheduledExecutionTime(n)=firstExecuteTime +n*periodTime,该计算方法永远保持不变。所以scheduleAtFixedRate更加侧重于保持执行频率的稳定。
    

    三、Timer的缺陷
    3.1、Timer的缺陷
    Timer计时器可以定时(指定时间执行任务)、延迟(延迟5秒执行任务)、周期性地执行任务(每隔个1秒执行任务),但是,Timer存在一些缺陷。首先Timer对调度的支持是基于绝对时间的,而不是相对时间,所以它对系统时间的改变非常敏感。其次Timer线程是不会捕获异常的,如果TimerTask抛出的了未检查异常则会导致Timer线程终止,同时Timer也不会重新恢复线程的执行,他会错误的认为整个Timer线程都会取消。同时,已经被安排单尚未执行的TimerTask也不会再执行了,新的任务也不能被调度。故如果TimerTask抛出未检查的异常,Timer将会产生无法预料的行为。

      1、Timer管理时间延迟缺陷
    
      前面Timer在执行定时任务时只会创建一个线程任务,如果存在多个线程,若其中某个线程因为某种原因而导致线程任务执行时间过长,超过了两个任务的间隔时间,会发生一些缺陷:
    

    [java] view plain copy
    public class TimerTest04 {
    private Timer timer;
    public long start;

    public TimerTest04(){  
        this.timer = new Timer();  
        start = System.currentTimeMillis();  
    }  
      
    public void timerOne(){  
        timer.schedule(new TimerTask() {  
            public void run() {  
                System.out.println("timerOne invoked ,the time:" + (System.currentTimeMillis() - start));  
                try {  
                    Thread.sleep(4000);    //线程休眠3000  
                } catch (InterruptedException e) {  
                    e.printStackTrace();  
                }  
            }  
        }, 1000);  
    }  
      
    public void timerTwo(){  
        timer.schedule(new TimerTask() {  
            public void run() {  
                System.out.println("timerOne invoked ,the time:" + (System.currentTimeMillis() - start));  
            }  
        }, 3000);  
    }  
      
    public static void main(String[] args) throws Exception {  
        TimerTest04 test = new TimerTest04();  
          
        test.timerOne();  
        test.timerTwo();  
    }  
    

    }
    public class TimerTest04 {
    private Timer timer;
    public long start;

    public TimerTest04(){
        this.timer = new Timer();
        start = System.currentTimeMillis();
    }
    
    public void timerOne(){
        timer.schedule(new TimerTask() {
            public void run() {
                System.out.println("timerOne invoked ,the time:" + (System.currentTimeMillis() - start));
                try {
                    Thread.sleep(4000);    //线程休眠3000
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, 1000);
    }
    
    public void timerTwo(){
        timer.schedule(new TimerTask() {
            public void run() {
                System.out.println("timerOne invoked ,the time:" + (System.currentTimeMillis() - start));
            }
        }, 3000);
    }
    
    public static void main(String[] args) throws Exception {
        TimerTest04 test = new TimerTest04();
        
        test.timerOne();
        test.timerTwo();
    }
    

    }
    按照我们正常思路,timerTwo应该是在3s后执行,其结果应该是:

    [java] view plain copy
    timerOne invoked ,the time:1001
    timerOne invoked ,the time:3001
    timerOne invoked ,the time:1001
    timerOne invoked ,the time:3001
    但是事与愿违,timerOne由于sleep(4000),休眠了4S,同时Timer内部是一个线程,导致timeOne所需的时间超过了间隔时间,结果:

    [java] view plain copy
    timerOne invoked ,the time:1000
    timerOne invoked ,the time:5000
    timerOne invoked ,the time:1000
    timerOne invoked ,the time:5000
    2、Timer抛出异常缺陷

      如果TimerTask抛出RuntimeException,Timer会终止所有任务的运行。如下:
    

    [html] view plain copy
    public class TimerTest04 {
    private Timer timer;

    public TimerTest04(){  
        this.timer = new Timer();  
    }  
      
    public void timerOne(){  
        timer.schedule(new TimerTask() {  
            public void run() {  
                throw new RuntimeException();  
            }  
        }, 1000);  
    }  
      
    public void timerTwo(){  
        timer.schedule(new TimerTask() {  
              
            public void run() {  
                System.out.println("我会不会执行呢??");  
            }  
        }, 1000);  
    }  
      
    public static void main(String[] args) {  
        TimerTest04 test = new TimerTest04();  
        test.timerOne();  
        test.timerTwo();  
    }  
    

    }
    public class TimerTest04 {
    private Timer timer;

    public TimerTest04(){
        this.timer = new Timer();
    }
    
    public void timerOne(){
        timer.schedule(new TimerTask() {
            public void run() {
                throw new RuntimeException();
            }
        }, 1000);
    }
    
    public void timerTwo(){
        timer.schedule(new TimerTask() {
            
            public void run() {
                System.out.println("我会不会执行呢??");
            }
        }, 1000);
    }
    
    public static void main(String[] args) {
        TimerTest04 test = new TimerTest04();
        test.timerOne();
        test.timerTwo();
    }
    

    }
    运行结果:timerOne抛出异常,导致timerTwo任务终止。

    [java] view plain copy
    Exception in thread “Timer-0” java.lang.RuntimeException
    at com.chenssy.timer.TimerTest04$1.run(TimerTest04.java:25)
    at java.util.TimerThread.mainLoop(Timer.java:555)
    at java.util.TimerThread.run(Timer.java:505)
    Exception in thread “Timer-0” java.lang.RuntimeException
    at com.chenssy.timer.TimerTest04$1.run(TimerTest04.java:25)
    at java.util.TimerThread.mainLoop(Timer.java:555)
    at java.util.TimerThread.run(Timer.java:505)
    对于Timer的缺陷,我们可以考虑 ScheduledThreadPoolExecutor 来替代。Timer是基于绝对时间的,对系统时间比较敏感,而ScheduledThreadPoolExecutor 则是基于相对时间;Timer是内部是单一线程,而ScheduledThreadPoolExecutor内部是个线程池,所以可以支持多个任务并发执行。

    3.2、用ScheduledExecutorService替代Timer
    1、解决问题一:

    [java] view plain copy
    public class ScheduledExecutorTest {
    private ScheduledExecutorService scheduExec;

    public long start;  
      
    ScheduledExecutorTest(){  
        this.scheduExec =  Executors.newScheduledThreadPool(2);    
        this.start = System.currentTimeMillis();  
    }  
      
    public void timerOne(){  
        scheduExec.schedule(new Runnable() {  
            public void run() {  
                System.out.println("timerOne,the time:" + (System.currentTimeMillis() - start));  
                try {  
                    Thread.sleep(4000);  
                } catch (InterruptedException e) {  
                    e.printStackTrace();  
                }  
            }  
        },1000,TimeUnit.MILLISECONDS);  
    }  
      
    public void timerTwo(){  
        scheduExec.schedule(new Runnable() {  
            public void run() {  
                System.out.println("timerTwo,the time:" + (System.currentTimeMillis() - start));  
            }  
        },2000,TimeUnit.MILLISECONDS);  
    }  
      
    public static void main(String[] args) {  
        ScheduledExecutorTest test = new ScheduledExecutorTest();  
        test.timerOne();  
        test.timerTwo();  
    }  
    

    }
    public class ScheduledExecutorTest {
    private ScheduledExecutorService scheduExec;

    public long start;
    
    ScheduledExecutorTest(){
        this.scheduExec =  Executors.newScheduledThreadPool(2);  
        this.start = System.currentTimeMillis();
    }
    
    public void timerOne(){
        scheduExec.schedule(new Runnable() {
            public void run() {
                System.out.println("timerOne,the time:" + (System.currentTimeMillis() - start));
                try {
                    Thread.sleep(4000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },1000,TimeUnit.MILLISECONDS);
    }
    
    public void timerTwo(){
        scheduExec.schedule(new Runnable() {
            public void run() {
                System.out.println("timerTwo,the time:" + (System.currentTimeMillis() - start));
            }
        },2000,TimeUnit.MILLISECONDS);
    }
    
    public static void main(String[] args) {
        ScheduledExecutorTest test = new ScheduledExecutorTest();
        test.timerOne();
        test.timerTwo();
    }
    

    }

      运行结果:
    

    [java] view plain copy
    timerOne,the time:1003
    timerTwo,the time:2005
    timerOne,the time:1003
    timerTwo,the time:2005

      2、解决问题二
    

    [java] view plain copy
    public class ScheduledExecutorTest {
    private ScheduledExecutorService scheduExec;

    public long start;  
      
    ScheduledExecutorTest(){  
        this.scheduExec =  Executors.newScheduledThreadPool(2);    
        this.start = System.currentTimeMillis();  
    }  
      
    public void timerOne(){  
        scheduExec.schedule(new Runnable() {  
            public void run() {  
                throw new RuntimeException();  
            }  
        },1000,TimeUnit.MILLISECONDS);  
    }  
      
    public void timerTwo(){  
        scheduExec.scheduleAtFixedRate(new Runnable() {  
            public void run() {  
                System.out.println("timerTwo invoked .....");  
            }  
        },2000,500,TimeUnit.MILLISECONDS);  
    }  
      
    public static void main(String[] args) {  
        ScheduledExecutorTest test = new ScheduledExecutorTest();  
        test.timerOne();  
        test.timerTwo();  
    }  
    

    }
    public class ScheduledExecutorTest {
    private ScheduledExecutorService scheduExec;

    public long start;
    
    ScheduledExecutorTest(){
        this.scheduExec =  Executors.newScheduledThreadPool(2);  
        this.start = System.currentTimeMillis();
    }
    
    public void timerOne(){
        scheduExec.schedule(new Runnable() {
            public void run() {
                throw new RuntimeException();
            }
        },1000,TimeUnit.MILLISECONDS);
    }
    
    public void timerTwo(){
        scheduExec.scheduleAtFixedRate(new Runnable() {
            public void run() {
                System.out.println("timerTwo invoked .....");
            }
        },2000,500,TimeUnit.MILLISECONDS);
    }
    
    public static void main(String[] args) {
        ScheduledExecutorTest test = new ScheduledExecutorTest();
        test.timerOne();
        test.timerTwo();
    }
    

    }

     运行结果:
    

    [java] view plain copy
    timerTwo invoked …
    timerTwo invoked …
    timerTwo invoked …
    timerTwo invoked …
    timerTwo invoked …
    timerTwo invoked …
    timerTwo invoked …
    timerTwo invoked …
    timerTwo invoked …

    timerTwo invoked …
    timerTwo invoked …
    timerTwo invoked …
    timerTwo invoked …
    timerTwo invoked …
    timerTwo invoked …
    timerTwo invoked …
    timerTwo invoked …
    timerTwo invoked …

    展开全文
  • Java定时任务

    千次阅读 2012-04-04 17:44:40
    在日常工作中,定时进行任务...在Java中由两个类完成定时任务的调度,分别为:java.util.Timer和java.util.TimerTask 创建一个定时任务的步聚: 1、创建一个定时器(Timer)对象 2、调用该对象的schedule(TimerTask
  • java定时任务,每天定时执行任务

    千次阅读 2017-10-20 00:33:56
    java定时任务,每天定时执行任务
  • Java 定时任务JOB

    千次阅读 2019-07-19 10:49:58
    Java 定时任务JOB创建过程 1.创建QuartzManager管理类。 如果需要可根据自身的需要对此类的方法进行重载,以符合自生业务 import org.quartz.CronTrigger; import org.quartz.JobDataMap; import org.quartz....
  • 详解java定时任务

    万次阅读 多人点赞 2014-06-20 12:07:10
    在我们编程过程中如果需要执行一些简单...一、简介 在java中一个完整定时任务需要由Timer、TimerTask两个类来配合完成。 API中是这样定义他们的,Timer:一种工具,线程用其安排以后在后台线程中执行的任务。可安排任
  • java定时任务 每天定时执行任务

    千次阅读 2015-04-23 19:38:02
    转载网址:http://www.open-open.com/lib/view/open1338175095183.html ... java定时任务,每天定时执行任务。以下是这个例子的全部代码。 ? 1 2
  • java定时任务实现的几种方式

    万次阅读 多人点赞 2017-10-13 09:58:48
    摘要: 在开发测试工具的应用后台,经常听到同事说要做个定时任务把做日志处理,或者数据清理,包括做些复杂的业务计算逻辑,在选择定时任务的时候,怎么能够快速实现,并且选择一种更适合自己的方式呢?我这里把...
  • JAVA定时任务-动态修改定时任务时间

    千次阅读 2020-05-23 18:40:02
    最近有个需求是这样的: 实现一个HDFS的Bucket.在总大小超过128M或10分钟内没有新文件时,进行上传操作. 所以需要实现一个可以修改定时时间的定时任务. 代码如下
  • Java实现简单定时任务一篇记录中描述的是Java的几种定时任务的方式,那是最基本的,仅仅是main方法里测试,用途也受限。 这里研究一下在web中怎么实现这些个定时任务,在这儿作个备忘: 在上一篇里我们都是在...
  • Java 定时任务实现原理详解

    万次阅读 多人点赞 2018-03-18 20:26:07
    在jdk自带的库中,有两种技术可以实现定时任务。一种是使用Timer,另外一个则是ScheduledThreadPoolExecutor。下面为大家分析一下这两个技术的底层实现原理以及各自的优缺点。 一、Timer 1. Timer的使用 ...
  • Java定时任务关闭

    万次阅读 2017-08-12 15:03:22
    创建定时任务时,如果我们不主动去取消定时任务,我们需要的任务内容执行完毕,但定时任务不会关闭。 启动定时任务时,相当于启动一个分线程, 下面写了两种: 一是通过定义参数,创建对象时,将定时器对象传入...
  • Java 定时任务配置文件

    千次阅读 2018-11-29 21:08:58
    Java 定时任务配置文件 配置文件: &lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi=&...
  • Java定时任务(1)

    千次阅读 2016-04-05 17:20:10
    Java定时任务之Timer & TimerTaskTimer & TimerTask 作为java的任务调度器之一,了解其内部原理有助于我们更好的理解它与其他调度器之间的异同。 TimerTask Timer及其调度过程 总结 TimerTaskTimerTask作为被...
  • Java定时任务(2)

    千次阅读 2016-04-07 20:11:38
    Java定时任务(2)上次浅显的分析了Timer及TimerTask的调度原理,这里我们再来看一下另一种定时调度方式ScheduledThreadPoolExecutor的内部执行原理。 ScheduledThreadPoolExecutor调度方式 阻塞队列...
  • JAVA定时任务Timer、Spring Task、Quartz

    千次阅读 2017-07-06 16:48:05
    JAVA定时任务 作者:高志远 2017/6/25 2:23:23 一、什么是定时任务: 定时任务是指调度程序在指定的时间或周期触发执行的任务 使用场景:发送邮件、统计、状态修改、消息推送、活动开启、增量索引 二、定时...
  • Java定时任务ScheduledThreadPoolExecutor

    千次阅读 2012-08-04 11:38:31
    以前定时任务一直用Timer这个类,后来发现ScheduledThreadPoolExecutor功能更强大,我们先看个简单的示例,然后再看看API中的描述: 这个定时任务是我的项目中,每隔5分钟去检查设备的在线状态的。 public ...
  • Java定时任务Cron表达式

    千次阅读 2019-11-08 11:32:05
    @Scheduled(cron = “0 30 6-22 ? * *”) 顺序 秒 分钟 小时 日期 月份 星期 年(可选) 取值 0-59 0-59 0-23 1-30(31) 1-12 1-7 允许特殊字符 , - * / , - * / , - * / , - * / ?...*:代表所有可能的...
  • java定时任务队列

    千次阅读 2019-05-20 10:04:48
    仅供参考,我是用来发送请求的,对方没有回应就重发,收到回应移除相关任务。 package test0517; import java.util.ArrayList; import java.util.Timer; import java.util.TimerTask; public class Main { ...
  • java定时任务实现的4种方式

    万次阅读 热门讨论 2018-12-12 13:27:39
    1. java自带的Timer Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { System.out.println("Time's up!"); ...
  • java 定时任务调用servlet

    千次阅读 2016-03-22 15:12:00
    解决:定时任务调用java方法,然后通过该方法发送http请求 package wzh.Http; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import...
  • java实现定时任务 Schedule

    万次阅读 多人点赞 2016-06-07 11:56:02
    java实现定时任务 Schedule
  • 浅谈java定时任务:TimerTask

    千次阅读 2017-03-31 20:51:15
    java 定时任务TimerTask定时任务有很多种实现,网上也有很多开源的定时任务框架可以参考,但博主只简单介绍一下博主使用到的四种定时任务的实现:Timer和TimerTaks、spring、quartz、spring和quartz。话不多说,直接...
  • Java 定时任务的几种实现方式

    万次阅读 多人点赞 2017-06-03 22:04:51
    JAVA实现定时任务的几种方式@(JAVA)[spring|quartz|定时器]  近期项目开发中需要动态的添加定时任务,比如在某个活动结束时,自动生成获奖名单,导出excel等,此类任务由于活动时间是动态的,不能把定时任务配置在...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 135,341
精华内容 54,136
关键字:

java定时任务如何测试

java 订阅