Timer,一般用来做延时、定时任务(一次性)或者循环定时执行的任务。
例如:指定在一小时后闹钟就响了,或者每天6:00响,这些都是延时任务或者是定时循环的任务。在使用Timer的时候,要新建TimerTask去执行任务,这是一个线程,它实现了Runnable接口,run方法里面就是线程需要做的,也是我们自己定义的。可以创建多个TimerTask然后添加到Timer里面,但是因为Timer里面本质是只有一个线程执行任务,所以使用起来有许多的弊端,这会在另外一篇博文里跟使用线程池作定时任务作比较。
代码如下:
try { Date mDate=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2018-05-10 11:48:00"); } catch (ParseException e) { e.printStackTrace(); } Timer myTimer=new Timer(); TimerTask timerTask=new TimerTask() { @Override public void run() { System.out.println(System.currentTimeMillis()); } };
在上面的代码中定义了一个Date,Timer以及TimerTask
下面看看在调用不同的构造方法使用的含义:
myTimer.schedule(timerTask, mDate); myTimer.schedule(timerTask, 1000); myTimer.schedule(timerTask, 1000,1000); myTimer.schedule(timerTask, mDate,1000); myTimer.scheduleAtFixedRate(timerTask, 3000, 1000); myTimer.scheduleAtFixedRate(timerTask, mDate, 1000*60*60*24);
在代码的前两行,只有两个参数,第一个是定时任务,第二个参数可以是Date也可以是long 型的时间,表示当前系统时间后1s的时间,这两种方式均表示任务只执行一次,不循环执行。
第3、4行代码比前两行多穿了一个间隔时间的参数,第三行表示在1S的延迟过后一直循环执行这个任务,任务的间隔时间是1S,第4行表示在mDate这个指定的日期循环执行这个任务,每次任务的间隔时间是1秒。
第5行代码跟第3行的代码含义一样,先延时执行一段时间,然后每隔一段时间循环执行任务。
第6行的代码与第4行的代码有区别,这个是schedule的执行,执行的时候的系统时间已经过了mDate,会先直接执行一次,然后开始每隔一秒后执行。myTimer.scheduleAtFixedRate(timerTask,mDate,1000*60*60*24)的执行,如果执行的时候的系统时间已经过了mDate,会先算出过了的时间里应该要执行几次,执行完这些次数后在等待下一次执行的到来,在执行的时候,比如你指定开始时间为16:30,每隔5分钟执行一次,而你是在系统时间16:48分开始运行程序,那么就会在16:30,16:35,16:40,16:45,16:50。。。这样执行下去(16:48这个时间不执行)。
这就是在指定时间已经过了的情况下的两者区别了,schedule是直接执行,并且以此刻为开始时间,开始执行,并且过去的不再执行。而scheduleAtFixedRate是判断时间,如果过了,那么就算出之前执行的次数,依次执行,然后等待下一次执行时间的到来。