摘要:筆記來源定時任務(wù)調(diào)度基于給定的時間點,給定的時間間隔或者給定的執(zhí)行次數(shù)自動執(zhí)行的任務(wù)??砂才湃蝿?wù)執(zhí)行一次,或者定期重復(fù)執(zhí)行。有且僅有一個后臺線程對多個業(yè)務(wù)線程進(jìn)行定時定頻率的調(diào)度。
筆記來源:IMOOC Java Timer定時任務(wù)調(diào)度
基于給定的時間點,給定的時間間隔或者給定的執(zhí)行次數(shù)自動執(zhí)行的任務(wù)。
Timer 定義一種工具,線程用其安排以后在后臺線程中執(zhí)行的任務(wù)??砂才湃蝿?wù)執(zhí)行一次,或者定期重復(fù)執(zhí)行。
有且僅有一個后臺線程對多個業(yè)務(wù)線程進(jìn)行定時定頻率的調(diào)度。
Timer 主要構(gòu)建 Timer 主要成分 Timer 定時調(diào)度函數(shù) schedule 的四種用法
schedule(task, time)
參數(shù)
task - 所要安排的任務(wù)
time - 執(zhí)行任務(wù)的時間
作用
在時間等于或超過time的時候執(zhí)行且僅執(zhí)行一次task
schedule(task, time, period)
參數(shù)
task - 所要安排的任務(wù)
time - 首次執(zhí)行任務(wù)的時間
period - 執(zhí)行一次task的時間間隔,單位是毫秒
作用
時間等于或超過time時首次執(zhí)行task,之后每隔period毫秒重復(fù)執(zhí)行一次task
schedule(task, delay)
參數(shù)
task - 所要安排的任務(wù)
delay - 執(zhí)行任務(wù)前的延遲時間,單位是毫秒
作用
等待delay毫秒后執(zhí)行且僅執(zhí)行一次task
schedule(task, delay, period)
參數(shù)
task - 所要安排的任務(wù)
delay - 執(zhí)行任務(wù)前的延遲時間,單位是毫秒
period - 執(zhí)行一次task的時間間隔,單位是毫秒
作用
等待delay毫秒后首次執(zhí)行task,之后每隔period毫秒重復(fù)執(zhí)行一次task
scheduleAtFixedRate 的兩種用法
scheduleAtFixedRate(task, time, period)
參數(shù)
task - 所要安排的任務(wù)
time - 首次執(zhí)行任務(wù)的時間
period - 執(zhí)行一次task的時間間隔,單位是毫秒
作用
時間等于或超過time時首次執(zhí)行task,之后每隔period毫秒重復(fù)執(zhí)行一次task
scheduleAtFixedRate(task, delay, period)
參數(shù)
task - 所要安排的任務(wù)
delay - 執(zhí)行任務(wù)前的延遲時間,單位是毫秒
period - 執(zhí)行一次task的時間間隔,單位是毫秒
作用
等待delay毫秒后首次執(zhí)行task,之后每隔period毫秒重復(fù)執(zhí)行一次task
Timer 示例import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.TimerTask; public class MyTimerTask extends TimerTask { private String name; public MyTimerTask(String inputName) { name = inputName; } @Override public void run() { // 以 yyyy-MM-dd HH:mm:ss 的格式打印當(dāng)前執(zhí)行時間 Calendar calendar = Calendar.getInstance(); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("Current exec time is: " + sf.format(calendar.getTime())); // 打印當(dāng)前name的內(nèi)容 System.out.println("Current exec name is: " + name); } public String getName() { return name; } public void setName(String name) { this.name = name; } }
import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Timer; public class MyTimer { public static void main(String[] args) { // 1. 創(chuàng)建一個timer實例 Timer timer = new Timer(); // 2. 創(chuàng)建一個MyTimerTask實例 MyTimerTask myTimerTask = new MyTimerTask("No.1"); /** * 獲取當(dāng)前時間,并設(shè)置成距離當(dāng)前時間三秒后的時間 */ Calendar calendar = Calendar.getInstance(); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("Current main time is: " + sf.format(calendar.getTime())); calendar.add(Calendar.SECOND, 3); // 3. 通過timer定時定頻率調(diào)用myTimerTask的業(yè)務(wù)邏輯 //-------------------schedule的四種用法-------------------// /** * 在時間等于或超過time的時間執(zhí)行且僅執(zhí)行一次task */ myTimerTask.setName("schedule_1"); timer.schedule(myTimerTask, calendar.getTime()); /** * 時間等于或超過time時首次執(zhí)行task,之后每隔period毫秒重復(fù)執(zhí)行一次task */ myTimerTask.setName("schedule_2"); timer.schedule(myTimerTask, calendar.getTime(), 2000); /** * 等待delay毫秒后執(zhí)行且僅執(zhí)行一次task */ myTimerTask.setName("schedule_3"); timer.schedule(myTimerTask, 1000); /** * 等待delay毫秒后首次執(zhí)行task,之后每隔period毫秒重復(fù)執(zhí)行一次task */ myTimerTask.setName("schedule_4"); timer.schedule(myTimerTask, 3000, 2000); //--------------scheduleAtFixedRate的兩種用法-------------// /** * 時間等于或超過time時首次執(zhí)行task,之后每隔period毫秒重復(fù)執(zhí)行一次task */ myTimerTask.setName("scheduleAtFixedRate_1"); timer.scheduleAtFixedRate(myTimerTask, calendar.getTime(), 2000); /** * 等待delay毫秒后首次執(zhí)行task,之后每隔period毫秒重復(fù)執(zhí)行一次task */ myTimerTask.setName("scheduleAtFixedRate_2"); timer.scheduleAtFixedRate(myTimerTask, 3000, 2000); } }schedule 與 scheduleAtFixedRate 的區(qū)別 首次計劃執(zhí)行的時間早于當(dāng)前的時間
schedule 方法
fixed-delay;如果第一次執(zhí)行時間被 delay 了,隨后的執(zhí)行時間按照上一次實際執(zhí)行完成的時間點進(jìn)行計算
scheduleAtFixedRate 方法
fixed-rate;如果第一次執(zhí)行時間被 delay 了,隨后的執(zhí)行時間按照上一次開始的時間點進(jìn)行計算,并且為了趕上進(jìn)度會多次執(zhí)行任務(wù),因此 TimerTask 中的執(zhí)行體需要考慮同步
任務(wù)執(zhí)行所需時間超出任務(wù)的執(zhí)行周期間隔
schedule 方法
下一次執(zhí)行時間相對于上一次實際執(zhí)行完成的時間點,因此執(zhí)行時間會不斷延后
scheduleAtFixedRate 方法
下一次執(zhí)行時間相對于上一次開始的時間點,因此執(zhí)行時間一般不會延后,因此存在并發(fā)性
其他重要函數(shù)TimerTask 的 cancel()、scheduleExecutionTime()
Timer 的 cancel()、purge()
TimerTask 的兩個重要函數(shù)
cancel()
作用:取消當(dāng)前 TimerTask 里的任務(wù)
scheduleExecutionTime()
作用:返回此任務(wù)最近實際執(zhí)行的已安排執(zhí)行的實際
返回:最近發(fā)生此任務(wù)執(zhí)行安排的時間,為Long類型
Timer 的其他函數(shù)
cancel()
終止此計時器,丟棄所有當(dāng)前已安排的任務(wù)
purge()
作用:從此計時器的任務(wù)隊列中移除所有已取消的任務(wù)
返回:從隊列中移除的任務(wù)數(shù)
Timer 函數(shù)的綜合應(yīng)用
模擬兩個機器人的定時行為
第一個機器人會隔兩秒打印最近一次計劃的時間、執(zhí)行內(nèi)容
第二個機器人會模擬往桶里倒水,直到桶里的水滿為止,然后停止工作
桶里的水滿了之后,第一個機器人再跳舞兩秒鐘,然后停止工作
/** * 跳舞的機器人 */ public class DancingRobot extends TimerTask { @Override public void run() { // 獲取最近的一次任務(wù)執(zhí)行的時間,并將其格式化 SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("Scheduled exec time is: " + sf.format(scheduledExecutionTime())); System.out.println("Dancing happily!"); } } /** * 倒水的機器人 */ public class WaterRobot extends TimerTask { private Timer timer; // 最大容量為5L private Integer bucketCapacity = 0; public WaterRobot(Timer inputTimer) { timer = inputTimer; } @Override public void run() { // 灌水直接至桶滿為止 if(bucketCapacity < 5){ System.out.println("Add 1L water into the bucket!"); bucketCapacity ++; } else { // 水滿之后就停止執(zhí)行 System.out.println("The number of canceled task in timer is: " + timer.purge()); cancel(); System.out.println("The waterRobot has been aborted"); System.out.println("The number of canceled task in timer is: " + timer.purge()); System.out.println("Current water is " + bucketCapacity + "L"); // 等待兩秒鐘,終止timer里面的所有內(nèi)容 try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } timer.cancel(); } } } public class Executor { public static void main(String[] args) { Timer timer = new Timer(); // 獲取當(dāng)前時間 Calendar calendar = Calendar.getInstance(); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("Current time is: " + sf.format(calendar.getTime())); DancingRobot dr = new DancingRobot(); WaterRobot wr = new WaterRobot(timer); timer.schedule(dr, calendar.getTime(), 2000); timer.scheduleAtFixedRate(wr, calendar.getTime(), 1000); } }Timer 的缺陷
管理并發(fā)任務(wù)的缺陷
Timer 有且只有一個線程去執(zhí)行定時任務(wù),如果存在多個任務(wù),且任務(wù)時間過長,會導(dǎo)致執(zhí)行效果與預(yù)期不符
當(dāng)任務(wù)拋出異常時的缺陷
如果 TimerTask 拋出 RuntimeException,Timer 會停止所有任務(wù)的運行
Timer 的使用禁區(qū)對時效性要求較高的多任務(wù)并發(fā)作業(yè)
對復(fù)雜的任務(wù)的調(diào)度
擴展閱讀Timer與ScheduledExecutorService間的抉擇
Java中定時任務(wù)的實現(xiàn):Timer與ScheduledExecutorService的不同
Java 幾種調(diào)度任務(wù)的Timer、ScheduledExecutor、 開源工具包 Quartz、開源工具包 JCronTab
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/71653.html
時間:2017年05月24日星期三說明:本文部分內(nèi)容均來自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com教學(xué)示例源碼:無個人學(xué)習(xí)源碼:https://github.com/zccodere/s... 第一章:課程介紹 1-1 課程介紹 什么是定時任務(wù)調(diào)度 基于給定的時間點,給定的時間間隔或者給定的執(zhí)行次數(shù)自動執(zhí)行的任務(wù) 在Java中的定時調(diào)度工具 Timer:小弟,能實現(xiàn)日常60%的定...
摘要:類是一個抽象類,由安排為一次執(zhí)行或重復(fù)執(zhí)行的任務(wù)。也是自帶的一個基于線程池設(shè)計的定時任務(wù)類。問題,則可以直接使用類實現(xiàn)自定義的定時調(diào)度規(guī)則。 定時調(diào)度作為后端開發(fā)人員,我們總會遇到這樣的業(yè)務(wù)場景:每周同步一批數(shù)據(jù);每半個小時檢查一遍服務(wù)器運行狀況;每天早上八點給用戶發(fā)送一份包含今日待辦事項的郵件,等等。 這些場景中都離不開定時器,就像一個定好時間規(guī)則的鬧鐘,它會在指定時間觸發(fā),執(zhí)行我們...
閱讀 3202·2023-04-26 01:39
閱讀 3354·2023-04-25 18:09
閱讀 1623·2021-10-08 10:05
閱讀 3241·2021-09-22 15:45
閱讀 2790·2019-08-30 15:55
閱讀 2401·2019-08-30 15:54
閱讀 3173·2019-08-30 15:53
閱讀 1335·2019-08-29 12:32