java关于Timerschedule执⾏定时任务
1、在应⽤开发中,经常需要⼀些周期性的操作,⽐如每5分钟执⾏某⼀操作等。对于这样的操作最⽅便、⾼效的实现⽅式就是使⽤java.util.Timer⼯具类。
private java.util.Timer timer;
timer = new Timer(true);
timer.schedule(
new java.util.TimerTask() { public void run() { //rver.checkNewMail(); 要操作的⽅法 } }, 0, 5*60*1000);
第⼀个参数是要操作的⽅法,第⼆个参数是要设定延迟的时间,第三个参数是周期的设定,每隔多长时间执⾏该操作。
使⽤这⼏⾏代码之后,Timer本⾝会每隔5分钟调⽤⼀遍rver.checkNewMail()⽅法,不需要⾃⼰启动线程。Timer本⾝也是多线程同步的,多个线程可以共⽤⼀个Timer,不需要外部的同步代码。
2、
(1)Timer.schedule(TimerTask task,Date time)安排在制定的时间执⾏指定的任务。
(2)Timer.schedule(TimerTask task,Date firstTime ,long period)安排指定的任务在指定的时间开始进⾏重复的固定延迟执⾏.
(3)Timer.schedule(TimerTask task,long delay)安排在指定延迟后执⾏指定的任务.
(4)Timer.schedule(TimerTask task,long delay,long period)安排指定的任务从指定的延迟后开始进⾏重复的固定延迟执⾏.
(5)Timer.scheduleAtFixedRate(TimerTask task,Date firstTime,long period)安排指定的任务在指定的时间开始进⾏重复的固定速率执⾏.
(6)Timer.scheduleAtFixedRate(TimerTask task,long delay,long period)安排指定的任务在指定的延迟后开始进⾏重复的固定速率执⾏.以下内容根据 The JavaTM Tutorial 和相关API doc翻译整理,以供⽇后参考:
1.概览
Timer是⼀种定时器⼯具,⽤来在⼀个后台线程计划执⾏指定任务。它可以计划执⾏⼀个任务⼀次或反复多次。
TimerTask⼀个抽象类,它的⼦类代表⼀个可以被Timer计划的任务。
简单的⼀个例程:
import java.util.Timer;
import java.util.TimerTask;
/**
* Simple demo that us java.util.Timer to schedule a task to execute
* once 5 conds have pasd.
*/
public class Reminder {
Timer timer;
public Reminder(int conds) {
timer = new Timer();
外研版小学英语
timer.schedule(new RemindTask(), conds*1000);
}
class RemindTask extends TimerTask {
public void run() {倡导绿色生活
System.out.println("Time's up!");
timer.cancel(); //Terminate the timer thread
}
}
public static void main(String args[]) {
System.out.println("About to schedule task.");
new Reminder(5);
System.out.println("Task scheduled.");
}
}
唯美电影
运⾏这个⼩例⼦,你会⾸先看到:
About to schedule task.
5秒钟之后你会看到:
戒夜奶Time's up!
这个⼩例⼦可以说明⼀些⽤Timer线程实现和计划执⾏⼀个任务的基础步骤:
实现⾃定义的TimerTask的⼦类,run⽅法包含要执⾏的任务代码,在这个例⼦⾥,这个⼦类就是RemindTask。
实例化Timer类,创建计时器后台线程。
实例化任务对象 (new RemindTask()).
制定执⾏计划。这⾥⽤schedule⽅法,第⼀个参数是TimerTask对象,第⼆个参数表⽰开始执⾏前的延时时间(单位是milliconds,这⾥定义了5000)。还有⼀种⽅法可以指定任务的执⾏时间,如下例,指定任务在11:执⾏:
//Get the Date corresponding to 11:01:00 pm today.
Calendar calendar = Instance();
calendar.t(Calendar.HOUR_OF_DAY, 23);
calendar.t(Calendar.MINUTE, 1);
calendar.t(Calendar.SECOND, 0);
Date time = Time();
timer = new Timer();
timer.schedule(new RemindTask(), time);
2.终⽌Timer线程
默认情况下,只要⼀个程序的timer线程在运⾏,那么这个程序就会保持运⾏。当然,你可以通过以下四种⽅法终⽌⼀个timer线程:
调⽤timer的cancle⽅法。你可以从程序的任何地⽅调⽤此⽅法,甚⾄在⼀个timer task的run⽅法⾥。
让timer线程成为⼀个daemon线程(可以在创建timer时使⽤new Timer(true)达到这个⽬地),这样当程序只有daemon线程的时候,它就会⾃动终⽌运⾏。
当timer相关的所有task执⾏完毕以后,删除所有此timer对象的引⽤(置成null),这样timer线程也会终⽌。
调⽤it⽅法,使整个程序(所有线程)终⽌。
Reminder 的例⼦使⽤了第⼀种⽅式。在这⾥不能使⽤第⼆种⽅式,因为这⾥需要程序保持运⾏直到timer的任务执⾏完成,如果设成daemon,那么当main线程结束的时候,程序只剩下timer这个daemon线程,于是程序不会等timer线程执⾏task就终⽌了。
有些时候,程序的终⽌与否并不只与timer线程有关。举个例⼦,如果我们使⽤AWT来beep,那么AW
T会⾃动创建⼀个⾮daemon线程来保持程序的运⾏。下⾯的代码我们对 Reminder做了修改,加⼊了beeping功能,于是我们需要加⼊it的调⽤来终⽌程序。
import java.util.Timer;
import java.util.TimerTask;
import java.awt.Toolkit;
/**
* Simple demo that us java.util.Timer to schedule a task to execute
* once 5 conds have pasd.
*/
public class ReminderBeep {
Toolkit toolkit;
Timer timer;
public ReminderBeep(int conds) {
toolkit = DefaultToolkit();
timer = new Timer();
timer.schedule(new RemindTask(), conds*1000);
}
class RemindTask extends TimerTask {
public void run() {
System.out.println("Time's up!");
toolkit.beep();
//timer.cancel(); //Not necessary becau we it
}
}
public static void main(String args[]) {
System.out.println("About to schedule task.");
new ReminderBeep(5);
System.out.println("Task scheduled.");
}
}
3.反复执⾏⼀个任务
先看⼀个例⼦:
public class AnnoyingBeep {
Toolkit toolkit;
Timer timer;
晚上跑步能减肥吗
public AnnoyingBeep() {
toolkit = DefaultToolkit();
timer = new Timer();
timer.schedule(new RemindTask(),
0, //initial delay
爱护眼睛的方法
1*1000); //subquent rate
}
class RemindTask extends TimerTask {
int numWarningBeeps = 3;
public void run() {
if (numWarningBeeps > 0) {
toolkit.beep();
System.out.println("Beep!");
numWarningBeeps--;
} el {
toolkit.beep();
女性性感图片
System.out.println("Time's up!");
//timer.cancel(); //Not necessary becau we it
}
}
}
.
..
长名}
执⾏,你会看到如下输出:
Task scheduled.
Beep!
Beep! //one cond after the first beep
Beep! //one cond after the cond beep
Time's up! //one cond after the third beep
这⾥使⽤了三个参数的schedule⽅法⽤来指定task每隔⼀秒执⾏⼀次。如下所列为所有Timer类⽤来制定计划反复执⾏task的⽅法:schedule(TimerTask task, long delay, long period)
schedule(TimerTask task, Date time, long period)
scheduleAtFixedRate(TimerTask task, long delay, long period)
scheduleAtFixedRate(TimerTask task, Date firstTime, long period)
当计划反复执⾏的任务时,如果你注重任务执⾏的平滑度,那么请使⽤schedule⽅法,如果你在乎的是任务的执⾏频度那么使⽤scheduleAtFixedRate⽅法。例如,这⾥使⽤了schedule⽅法,这就意味着所有beep之间的时间间隔⾄少为1秒,也就是说,如果有⼀个beap因为某种原因迟到了(未按计划执⾏),那么余下的所有beep都要延时执⾏。如果我们想让这个程序正好在3秒以后终⽌,⽆论哪⼀个beep因为什么原因被延时,那么我们需要使⽤scheduleAtFixedRate⽅法,这样当第⼀个beep迟到时,那么后⾯的beep就会以最快的速度紧密执⾏(最⼤限度的压缩间隔时间)。
4.进⼀步分析schedule和scheduleAtFixedRate
(1) 2个参数的schedule在制定任务计划时,如果指定的计划执⾏时间scheduledExecutionTime<= systemCurrentTime,则task会被⽴即执⾏。scheduledExecutionTime不会因为某⼀个task的过度执⾏⽽改变。
(2) 3个参数的schedule在制定反复执⾏⼀个task的计划时,每⼀次执⾏这个task的计划执⾏时间随着前⼀次的实际执⾏时间⽽变,也就是scheduledExecutionTime(第n+1次)=realExecutionTime(第n次)
+periodTime。也就是说如果第n 次执⾏task时,由于某种原因这次执⾏时间过长,执⾏完后的systemCurrentTime>= scheduledExecutionTime(第n+1次),则此时不做时隔等待,⽴即执⾏第n+1次task,⽽接下来的第n+2次task的 scheduledExecutionTime(第n+2次)就随着变成了realExecutionTime(第n+1次)+periodTime。说⽩了,这个⽅法更注重保持间隔时间的稳定。
(3)3个参数的scheduleAtFixedRate在制定反复执⾏⼀个task的计划时,每⼀次执⾏这个task的计划执⾏时间在最初就被定下来了,也就是scheduledExecutionTime(第n次)=firstExecuteTime +n*periodTime;如果第n次执⾏task时,由于某种原因这次执⾏时间过长,执⾏完后的systemCurrentTime>= scheduledExecutionTime(第n+1次),则此时不做period间隔等待,⽴即执⾏第n+1次task,⽽接下来的第n+2次的task的scheduledExecutionTime(第n+2次)依然还是firstExecuteTime+(n+2)*periodTime这在第⼀次执⾏task就定下来了。说⽩了,这个⽅法更注重保持执⾏频率的稳定。