• java之定时器任务Timer用法


    在项目开发中,经常会遇到需要实现一些定时操作的任务,写过很多遍了,然而每次写的时候,总是会对一些细节有所遗忘,后来想想可能是没有总结的缘故,所以今天小编就打算总结一下可能会被遗忘的小点:

     1. public void schedule(TimerTask task,Date time) 这个方法中如启动时,已经过了time的时间,则系统会在启动后直接执行一次,
        话不多少直接上代码
    package com.test.timer.task;
    
    import java.text.DateFormat;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.Timer;
    import java.util.TimerTask;
    
    import org.junit.Test;
    
    /**
     * 
     * java实现定时器的若干方法
     * 
     * @author jimi
     *
     */
    public class TestTask {
        
        private static Timer timer = new Timer();
        
        private static DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
        
        public static void main(String[] args){
            Calendar calendar = Calendar.getInstance();
            int year = calendar.get(Calendar.YEAR);       
            int month = calendar.get(Calendar.MONTH);
            int day = calendar.get(Calendar.DAY_OF_MONTH);
            calendar.set(year,month,day,20,35,00);
            
            //如果这个时间已经过了,则会启动会立即执行一次
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    System.out.println("固定执行任务的时间:" + dateFormat.format(new Date()));
                }
            }, calendar.getTime());
        }
        
    }
    代码中我指定在当天的20时35分执行,启动程序后的结果如下:


    可以看到我程序是在20:40:47执行的,已经超过我设置的20时35分00秒,所以启动后直接执行一次。


    2.
    schedule(TimerTask task,long delay,long period) 和 scheduleAtFixedRate(TimerTask task,long delay,long period)方法的区别
    简单来说就是定时执行
    scheduleAtFixedRate不受外界影响,假如某一次TimerTask执行时间超过了定时执行周期,下一次执行时间不会受该任务执行时间的影响,
    依然会在指定时间执行,而
    schedule则会受影响,直接上代码来看:

    package com.test.timer.task;
    
    import java.text.DateFormat;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Timer;
    import java.util.TimerTask;
    
    /**
     * 
     * java实现定时器的若干方法
     * 
     * @author jimi
     *
     */
    public class TestTask {
        
        private static Timer timer = new Timer();
        
        private static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        
        private static int index = 0;
        
        public static void main(String[] args) throws ParseException{
            
            //固定速率
            timer.scheduleAtFixedRate(new TimerTask() {
                        @Override
                        public void run() {
                            index++;
                            if (index % 5 == 0){
                                try {
                                    Thread.sleep(5000);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            }
                            System.out.println("每隔4秒执行一次:" + dateFormat.format(new Date()));
                        }
                    }, 0, 4000);
            
        }
        
    }
    
    

    从代码可以看出,在index为5的倍数时,程序会休眠5秒,我们了来看看执行的结果

    每隔4秒执行一次:2018-08-10 19:12:09
    每隔4秒执行一次:2018-08-10 19:12:13
    每隔4秒执行一次:2018-08-10 19:12:17
    每隔4秒执行一次:2018-08-10 19:12:21
    每隔4秒执行一次:2018-08-10 19:12:30
    每隔4秒执行一次:2018-08-10 19:12:30
    每隔4秒执行一次:2018-08-10 19:12:33
    每隔4秒执行一次:2018-08-10 19:12:37
    每隔4秒执行一次:2018-08-10 19:12:41
    每隔4秒执行一次:2018-08-10 19:12:50
    每隔4秒执行一次:2018-08-10 19:12:50
    每隔4秒执行一次:2018-08-10 19:12:53
    每隔4秒执行一次:2018-08-10 19:12:57
    每隔4秒执行一次:2018-08-10 19:13:01
    每隔4秒执行一次:2018-08-10 19:13:10
    每隔4秒执行一次:2018-08-10 19:13:10

    我们可以看出在第五次和第六次同时运行,且第七次的时间并未是在19:12:30的基础加4秒,而是在程序启动后预先计算好的时间也就是19:12:33秒,所可以看scheduleAtFixedRate的执行时间是按照预先的固定速率来执行,不会因为某一次的延迟而影响后面的计划时间。

    我们再来看看schedule的代码和执行情况

    package com.test.timer.task;
    
    import java.text.DateFormat;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Timer;
    import java.util.TimerTask;
    
    /**
     * 
     * java实现定时器的若干方法
     * 
     * @author jimi
     *
     */
    public class TestTask {
        
        private static Timer timer = new Timer();
        
        private static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        
        private static int index = 0;
        
        public static void main(String[] args) throws ParseException{
            
            //非固定速率
            timer.schedule(new TimerTask() {
                
                @Override
                public void run() {
                    index++;
                    if (index % 5 == 0){
                        try {
                            Thread.sleep(5000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println("每隔4秒执行一次:" + dateFormat.format(new Date()));
                }
            }, 0, 4000);
        }
        
    }

    执行情况如下

    每隔4秒执行一次:2018-08-10 19:17:12
    每隔4秒执行一次:2018-08-10 19:17:16
    每隔4秒执行一次:2018-08-10 19:17:20
    每隔4秒执行一次:2018-08-10 19:17:24
    每隔4秒执行一次:2018-08-10 19:17:33
    每隔4秒执行一次:2018-08-10 19:17:33
    每隔4秒执行一次:2018-08-10 19:17:37
    每隔4秒执行一次:2018-08-10 19:17:41
    每隔4秒执行一次:2018-08-10 19:17:45
    每隔4秒执行一次:2018-08-10 19:17:54
    每隔4秒执行一次:2018-08-10 19:17:54
    每隔4秒执行一次:2018-08-10 19:17:58

    可以看出schedule在执行完第5、6次任务后,第7次的时间则是按照定时计划4秒后执行的,可见schedule在任务执行过程中,如果某一次任务延时,则后续任务会跟着延时后的时间重新计算定时执行时间。

    好了,小编今天就先码到这里,后面可能还会再介绍spring的定时任务,以及spring+quartz实现的定时任务。

     
    
    
     



    
    
    
  • 相关阅读:
    Executors提供的四种线程池和自定义线程池
    ava8并发教程:Threads和Executors
    Java 信号量 Semaphore 介绍
    Condition-线程通信更高效的方式
    ReentrantLock详解 以及与synchronized的区别
    FutureTask 源码解析
    Java多线程编程:Callable、Future和FutureTask浅析
    Callable 和 Runnable 的区别
    javascript之url转义escape()、encodeURI()和decodeURI()
    yii2.0安装ElasticSearch及使用
  • 原文地址:https://www.cnblogs.com/ljy-20180122/p/9404426.html
Copyright © 2020-2023  润新知