Java自帶的java.util.Timer類,通過調度一個java.util.TimerTask任務。這種方式可以讓程序按照某一個頻度執(zhí)行,但不能指定時間運行。用的較少。
任務的調用通過起的子線程進行執(zhí)行。
java.util.Timer
java.util.TimerTask
一、調用方法:
(1)void java.util.Timer.schedule(TimerTask task, long delay):多長時間(毫秒)后執(zhí)行任務
(2)void java.util.Timer.schedule(TimerTask task, Date time):設定某個時間執(zhí)行任務
(3)void java.util.Timer.schedule(TimerTask task, long delay, long period):delay時間后開始執(zhí)行任務,并每隔period時間調用任務一次。
(4)void java.util.Timer.schedule(TimerTask task, Date firstTime, long period):第一次在指定firstTime時間點執(zhí)行任務,之后每隔period時間調用任務一次。
(5)void java.util.Timer.scheduleAtFixedRate(TimerTask task, long delay, long period):delay時間后開始執(zhí)行任務,并每隔period時間調用任務一次。
(6)void java.util.Timer.scheduleAtFixedRate(TimerTask task, long delay, long period):第一次在指定firstTime時間點執(zhí)行任務,之后每隔period時間調用任務一次。
void java.util.Timer.cancel():終止該Timer
boolean java.util.TimerTask.cancel():終止該TimerTask
可以為每個Timer指定多個TimerTask
雖然可通過void java.util.Timer.schedule(TimerTask task, Date firstTime, long period)方法完成“例如:每天上午10點執(zhí)行一次”的業(yè)務,但該實現(xiàn)是基于進行一天(1000 * 60 * 60 * 24毫秒)進行延遲的機制實現(xiàn)的,并不是指定某個具體時間進行執(zhí)行的。
對于該種需求,可通過Quartz來進行實現(xiàn)
二、方法名稱schedule()和scheduleAtFixedRate()兩者的區(qū)別
當需要根據(jù)period區(qū)間時間循環(huán)多次調用任務的時候,會存在兩種不同的策略,兩種方法提供了不同的策略。
調用方法(1)、(2)只是單次執(zhí)行,不存在多次調用任務的情況,所以沒有提供scheduleAtFixedRate方法的調用方式。
<1>schedule()方法更注重保持間隔時間的穩(wěn)定:保障每隔period時間可調用一次
<2>scheduleAtFixedRate()方法更注重保持執(zhí)行頻率的穩(wěn)定:保障多次調用的頻率趨近于period時間,如果某一次調用時間大于period,下一次就會盡量小于period,以保障頻率接近于period
三、示例
(1)
- /**
- * 第一種方法:設定多長時間(毫秒)后執(zhí)行任務
- */
- public static void timer1() {
- final StopWatch watch = new StopWatch();
- watch.start();
- Timer timer = new Timer();
- /* void java.util.Timer.schedule(TimerTask task, long delay) */
- timer.schedule(new TimerTask() {
- public void run() {
- watch.stop();
- System.out.println("-------任務執(zhí)行--------");
- System.out.println(watch.getTime());
- }
- }, 2000);// delay=2000毫秒 后執(zhí)行該任務
- }
(2)
- /**
- * 第二種方法:設定某個時間執(zhí)行任務
- */
- public static void timer2() {
- Calendar calendar = new GregorianCalendar();
- calendar.add(Calendar.MINUTE, 1);
- calendar.set(Calendar.SECOND, 0); // 一分鐘后執(zhí)行
- Timer timer = new Timer();
- /* void java.util.Timer.schedule(TimerTask task, Date time) */
- timer.schedule(new TimerTask() {
- @Override
- public void run() {
- System.out.println("-------任務執(zhí)行--------");
- }
- }, calendar.getTime());
- }
(3)
- /**
- * 第三種方法:設定指定任務task在指定延遲delay后進行固定延遲peroid的執(zhí)行
- */
- public static void timer3() {
- Timer timer = new Timer();
- final StopWatch watch = new StopWatch();
- watch.start();
- System.out.println(Thread.currentThread().getName());
- /*
- * void java.util.Timer.schedule(TimerTask task, long delay, long
- * period)
- */
- timer.schedule(new TimerTask() {
- public void run() {
- /* 子線程進行任務的執(zhí)行 */
- System.out.println(Thread.currentThread().getName());
- System.out.println("-------設定要指定任務--------");
- watch.suspend();
- System.out.println(watch.getTime());
- watch.reset();
- watch.start();
- }
- }, 1000, 1000);
- }
(4)
- /**
- * 固定延遲peroid時間后執(zhí)行;peroid時間不是以任務執(zhí)行完的時間為計算起點(某次任務執(zhí)行完成后,經過peroid時間后再次調用[不是這樣的])。
- * 而是每隔peroid時間調用任務一次。當任務執(zhí)行的時間小于peroid時間,可以保證每隔peroid時間調用一次。
- * 當任務的執(zhí)行時間大于peroid時間時,從現(xiàn)象上看:任務一執(zhí)行完,就會立刻進入下一次任務的執(zhí)行
- */
- public static void timer3a() {
- Timer timer = new Timer();
- final StopWatch watch = new StopWatch();
- watch.start();
- timer.schedule(new TimerTask() {
- Integer i = 1;
- public void run() {
- System.out.println(watch.getTime());
- System.out.println("########第" + i + "次執(zhí)行開始########");
- try {
- Thread.sleep(400);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println("########第" + i + "次執(zhí)行結束########");
- i++;
- watch.reset();
- watch.start();
- }
- }, 1000, 500);
- }
period:500毫秒;每次任務執(zhí)行時間400毫秒;所以每次任務執(zhí)行完成后到下一次任務調用開始的時間趨近于100毫秒
打印日志信息:
- 1000
- ########第1次執(zhí)行開始########
- ########第1次執(zhí)行結束########
- 109
- ########第2次執(zhí)行開始########
- ########第2次執(zhí)行結束########
- 93
- ########第3次執(zhí)行開始########
- ########第3次執(zhí)行結束########
- 93
- ########第4次執(zhí)行開始########
- ########第4次執(zhí)行結束########
- 93
- ########第5次執(zhí)行開始########
- ########第5次執(zhí)行結束########
- 93
- ########第6次執(zhí)行開始########
- ########第6次執(zhí)行結束########
- 93
- ########第7次執(zhí)行開始########
- ########第7次執(zhí)行結束########
- 93
- ########第8次執(zhí)行開始########
當將Thread.sleep(400);修改為Thread.sleep(600)時:
打印日志信息:
- 1000
- ########第1次執(zhí)行開始########
- ########第1次執(zhí)行結束########
- 0
- ########第2次執(zhí)行開始########
- ########第2次執(zhí)行結束########
- 0
- ########第3次執(zhí)行開始########
- ########第3次執(zhí)行結束########
- 0
- ########第4次執(zhí)行開始########
- ########第4次執(zhí)行結束########
- 0
- ########第5次執(zhí)行開始########
(5)
- /**
- * 第四種方法:安排指定的任務task在指定的時間firstTime開始進行重復的固定速率period執(zhí)行
- * 每天中午12點都執(zhí)行一次
- */
- public static void timer4() {
- Calendar calendar = Calendar.getInstance();
- calendar.set(Calendar.HOUR_OF_DAY, 12); // 控制時
- calendar.set(Calendar.MINUTE, 0); // 控制分
- calendar.set(Calendar.SECOND, 0); // 控制秒
-
- Date time = calendar.getTime(); // 得出執(zhí)行任務的時間,此處為今天的12:00:00
-
- Timer timer = new Timer();
- /* void java.util.Timer.schedule(TimerTask task, Date firstTime, long period) */
- timer.schedule(new TimerTask() {
- public void run() {
- System.out.println("-------設定要指定任務--------");
- }
- }, time, 1000 * 60 * 60 * 24);// 這里設定將延時每天固定執(zhí)行
- }
(6)
- /**
- * 第五種方法:設定指定任務task在指定延遲delay后進行固定頻率peroid的執(zhí)行。
- * timer.schedule和timer.scheduleAtFixedRate的區(qū)別:
- * (1)schedule()方法更注重保持間隔時間的穩(wěn)定:保障每隔period時間可調用一次
- * (2)scheduleAtFixedRate()方法更注重保持執(zhí)行頻率的穩(wěn)定:保障多次調用的頻率趨近于period時間,如果某一次調用時間大于period,下一次就會盡量小于period,以保障頻率接近于period
- */
- public static void timer5() {
- Timer timer = new Timer();
- /* void java.util.Timer.scheduleAtFixedRate(TimerTask task, long delay, long period) */
- timer.scheduleAtFixedRate(new TimerTask() {
- public void run() {
- System.out.println("-------設定要指定任務--------");
- }
- }, 1000, 500);
- }
|