時間:2017年05月24日星期三
說明:本文部分內(nèi)容均來自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com
教學(xué)示例源碼:無
個人學(xué)習(xí)源碼:https://github.com/zccodere/s...
什么是定時任務(wù)調(diào)度
基于給定的時間點(diǎn),給定的時間間隔或者給定的執(zhí)行次數(shù)自動執(zhí)行的任務(wù)
在Java中的定時調(diào)度工具
Timer:小弟,能實現(xiàn)日常60%的定時任務(wù) Quartz:大哥,能搞定一切
Timer與Quartz區(qū)別
出身不同 Timer由JDK提供,調(diào)用方式簡單粗暴,不需要別的jar包支持 Quartz源于開源項目,非JDK自帶,需要引入別的jar包支持 能力區(qū)別:主要體現(xiàn)在對時間的控制上 Timer實現(xiàn)如某個具體時間執(zhí)行什么任務(wù) Quartz實現(xiàn)如每個星期天8點(diǎn)執(zhí)行什么任務(wù) Quartz的時間控制功能遠(yuǎn)比Timer強(qiáng)大和完善 底層機(jī)制 Timer走后臺線程執(zhí)行定時任務(wù) Quartz能夠使用多個執(zhí)行線程去執(zhí)行定時任務(wù) Quartz確實比Timer強(qiáng)大很多,但是,Timer能實現(xiàn)的功能,盡量不動用Quartz 畢竟大哥的出場費(fèi)要比小弟高
前置知識
第二章:Timer簡介 2-1 Timer簡介本節(jié)內(nèi)容
Timer紙上談兵:Timer的定義以及架構(gòu) Timer實戰(zhàn)演練:通過一個實際的例子,讓大家對Timer有一個初步的了解
Timer的定義
有且僅有一個后臺線程對多個業(yè)務(wù)線程進(jìn)行定時定頻率的調(diào)度
主要構(gòu)件
Timer工具類詳解
通過程序來講解Timer
代碼演示
1.編寫需定時調(diào)度的業(yè)務(wù)邏輯類
package com.myimooc.timer; import java.util.TimerTask; /** * 需定時調(diào)度的業(yè)務(wù)邏輯類 * Created by ChangComputer on 2017/5/24. */ // 繼承 TimerTask 類 public class MyTimerTask extends TimerTask{ private String name; public MyTimerTask(String name){ this.name = name; } // 重寫 run 方法 @Override public void run() { // 打印當(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; } }
2.編寫定時調(diào)度類
package com.myimooc.timer; import java.util.Timer; /** * 定時調(diào)度類 * Created by ChangComputer on 2017/5/24. */ public class MyTimer { public static void main(String[] args){ // 創(chuàng)建一個 Timer 實例 Timer timer = new Timer(); // 創(chuàng)建一個 MyTimerTask 實例 MyTimerTask myTimerTask = new MyTimerTask("No.1"); // 通過 Timer 定時定頻率調(diào)用 MyTimerTask 的業(yè)務(wù)邏輯 // 即第一次執(zhí)行是在當(dāng)前時間的兩秒之后,之后每隔一秒鐘執(zhí)行一次 timer.schedule(myTimerTask,2000L,1000L); } }第三章:Timer函數(shù)和綜合應(yīng)用 3-1 Timer定時函數(shù)的用法
本節(jié)內(nèi)容
schedule的四種用法 scheduleAtFixedRate的兩種用法
第一種用法:schdule(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(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
代碼演示
1.修改需定時調(diào)度的業(yè)務(wù)邏輯類
/** * 需定時調(diào)度的業(yè)務(wù)邏輯類 * Created by ChangComputer on 2017/5/24. */ // 繼承 TimerTask 類 public class MyTimerTask extends TimerTask{ private String name; public MyTimerTask(String name){ this.name = name; } // 重寫 run 方法 @Override public void run() { // 以yyyy-MM-dd HH:mm:ss的格式打印當(dāng)前執(zhí)行時間 // 如2016-11-11 00:00:00 Calendar calendar = Calendar.getInstance(); // 定義日期格式 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("Current exec time is : " + simpleDateFormat.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; } }
2.修改定時調(diào)度類
package com.myimooc.timer; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Timer; /** * 定時調(diào)度類 * Created by ChangComputer on 2017/5/24. */ public class MyTimer { public static void main(String[] args){ // 創(chuàng)建一個 Timer 實例 Timer timer = new Timer(); // 創(chuàng)建一個 MyTimerTask 實例 MyTimerTask myTimerTask = new MyTimerTask("No.1"); // 通過 Timer 定時定頻率調(diào)用 MyTimerTask 的業(yè)務(wù)邏輯 // 即第一次執(zhí)行是在當(dāng)前時間的兩秒之后,之后每隔一秒鐘執(zhí)行一次 //timer.schedule(myTimerTask,2000L,1000L); /** * 獲取當(dāng)前時間,并設(shè)置成距離當(dāng)前時間三秒之后的時間 * 如當(dāng)前時間是2016-11-10 23:59:57 * 則設(shè)置后的時間則為2016-11-11 00:00:00 */ Calendar calendar = Calendar.getInstance(); // 定義日期格式 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("Current exec time is : " + simpleDateFormat.format(calendar.getTime())); calendar.add(Calendar.SECOND,3); // schedule的四種用法 /** * 1.在時間等于或超過time的時候執(zhí)行僅且執(zhí)行一次task * 如在2016-11-11 00:00:00執(zhí)行一次task,打印任務(wù)名字 */ //myTimerTask.setName("schedule1"); //timer.schedule(myTimerTask,calendar.getTime()); /** * 2.時間等于或超過time首次執(zhí)行task * 之后每隔period毫秒重復(fù)執(zhí)行一次task * 如在2016-11-11 00:00:00第一次執(zhí)行task,打印任務(wù)名字 * 之后每隔兩秒執(zhí)行一次task */ //myTimerTask.setName("schedule2"); //timer.schedule(myTimerTask,calendar.getTime(),2000L); /** * 3.等待delay毫秒后僅執(zhí)行且執(zhí)行一個task * 如現(xiàn)在是2016-11-11 00:00:00 * 則在2016-11-11 00:00:01執(zhí)行一次task,打印任務(wù)名字 */ //myTimerTask.setName("schedule3"); //timer.schedule(myTimerTask,1000L); /** * 4.等到delay毫秒后首次執(zhí)行task * 之后每隔period毫秒重復(fù)執(zhí)行一次task * 如現(xiàn)在是2016-11-11 00:00:00 * 則在2016-11-11 00:00:01第一次執(zhí)行task,打印任務(wù)名字 * 之后每隔兩秒執(zhí)行一次task */ //myTimerTask.setName("schedule4"); //timer.schedule(myTimerTask,1000L,2000L); // scheduleAtFixedRate的兩種用法 /** * 1.時間等于或超過time時首次執(zhí)行task * 之后每隔period毫秒重復(fù)執(zhí)行一次task * 如在2016-11-11 00:00:00第一次執(zhí)行task,打印任務(wù)名字 * 之后每隔兩秒執(zhí)行一次task */ //myTimerTask.setName("scheduleAtFixedRate1"); //timer.scheduleAtFixedRate(myTimerTask,calendar.getTime(),2000L); /** * 2.等待delay毫秒后首次執(zhí)行task * 之后每隔period毫秒重復(fù)執(zhí)行一次task * 如現(xiàn)在是2016-11-11 00:00:00 * 則在2016-11-11 00:00:01第一次執(zhí)行task,打印任務(wù)名字 * 之后每隔兩秒執(zhí)行一次task */ myTimerTask.setName("scheduleAtFixedRate2"); timer.scheduleAtFixedRate(myTimerTask,1000L,2000L); } }3-2 其他重要函數(shù)
本節(jié)內(nèi)容
TimerTask的cancel(), scheduleExecutionTime() Timer的cancel(), purge()
TimerTask類的cancel()
作用 取消當(dāng)前TimerTask里的任務(wù)
TimerTask類的scheduleExecutionTime()
作用 返回此任務(wù)最近實際執(zhí)行的已安排執(zhí)行的時間 返回值 最近發(fā)生此任務(wù)執(zhí)行安排的時間,為long型
Timer的cancel()
作用 終止此計時器,丟棄所有當(dāng)前已安排的任務(wù)
Timer的purge()
作用 從此計時器的任務(wù)隊列中移除所有已取消的任務(wù) 返回值 從隊列中移除的任務(wù)數(shù)
代碼演示
package com.myimooc.timer; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Timer; /** * Created by ChangComputer on 2017/5/24. */ public class CancelTest { public static void main(String[] args) throws InterruptedException { // 創(chuàng)建Timer實例 Timer timer = new Timer(); // 創(chuàng)建TimerTask實例 MyTimerTask task1 = new MyTimerTask("task1"); MyTimerTask task2 = new MyTimerTask("task2"); // 獲取當(dāng)前的執(zhí)行時間并打印 Date startTime = new Date(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("start time is : " + simpleDateFormat.format(startTime)); // task1首次執(zhí)行是距離現(xiàn)在時間3秒后執(zhí)行,之后每隔2秒執(zhí)行一次 // task1首次執(zhí)行是距離現(xiàn)在時間1秒后執(zhí)行,之后每隔2秒執(zhí)行一次 timer.schedule(task1,3000L,2000L); timer.schedule(task2,1000L,2000L); System.out.println("current canceled task number is : " + timer.purge()); // 休眠5秒 Thread.sleep(2000L); // 獲取當(dāng)前的執(zhí)行時間并打印 Date cancelTime = new Date(); System.out.println("cancel time is : " + simpleDateFormat.format(cancelTime)); // 取消所有任務(wù) // timer.cancel(); task2.cancel(); //System.out.println("Tasks all canceled!"); System.out.println("current canceled task number is : " + timer.purge()); } }3-3 schedule和scheduleAtFixedRate的區(qū)別
兩種情況看區(qū)別
首次計劃執(zhí)行的時間早于當(dāng)前的時間 任務(wù)執(zhí)行所需時間超出任務(wù)的執(zhí)行周期間隔
首次計劃執(zhí)行的時間早于當(dāng)前的時間
1.schedule方法 “fixed-delay”,如果第一次執(zhí)行時間被delay了, 隨后的執(zhí)行時間按照上一次實際執(zhí)行完成的時間點(diǎn)進(jìn)行計算 2.scheduleAtFixedRate方法 “fixed-rate”,如果第一次執(zhí)行時間被delay了, 隨后的執(zhí)行時間按照上一次開始的時間點(diǎn)進(jìn)行計算, 并且為了趕上進(jìn)度會多次執(zhí)行任務(wù),因此TimerTask中的執(zhí)行體需要考慮同步
代碼演示
package com.myimooc.timer; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Timer; import java.util.TimerTask; /** * schedule和scheduleAtFixedRate的區(qū)別 測試類 * Created by ChangComputer on 2017/5/24. */ public class DifferenceTest { public static void main(String[] args){ // 定義時間格式 final SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 獲取當(dāng)前的具體時間 Calendar calendar = Calendar.getInstance(); System.out.println("Current time is : " + sf.format(calendar.getTime())); // 設(shè)置成6秒前的時間,若當(dāng)前時間為2016-12-28 00:00:06 // 那么設(shè)置之后時間變成2016-12-28 00:00:00 calendar.add(Calendar.SECOND,-6); Timer timer = new Timer(); // 第一次執(zhí)行時間為6秒前,之后每隔兩秒鐘執(zhí)行一次 //timer.schedule(new TimerTask() { timer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { // 打印當(dāng)前的計劃執(zhí)行時間 System.out.println("Schedule exec time is : " + sf.format(scheduledExecutionTime())); System.out.println("Task is being executed!"); } }, calendar.getTime(), 2000); } }
任務(wù)執(zhí)行所需時間超出任務(wù)的執(zhí)行周期間隔
1. schedule方法 下一次執(zhí)行時間相對于上一次實際執(zhí)行完成的時間點(diǎn),因此執(zhí)行時間會不斷延后 2.scheduleAtFixedRate方法 下一次執(zhí)行時間相對于上一次開始的時間點(diǎn),因此執(zhí)行時間一般不會延后,因此存在并發(fā)性
代碼演示
package com.myimooc.timer; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Timer; import java.util.TimerTask; /** * schedule和scheduleAtFixedRate的區(qū)別 測試類 * Created by ChangComputer on 2017/5/24. */ public class DifferenceTwoTest { public static void main(String[] args){ // 定義時間格式 final SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 獲取當(dāng)前的具體時間 Calendar calendar = Calendar.getInstance(); System.out.println("Current time is : " + sf.format(calendar.getTime())); Timer timer = new Timer(); //timer.schedule(new TimerTask() { timer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { try { Thread.sleep(3000L); } catch (InterruptedException e) { e.printStackTrace(); } // 打印最近一次的計劃執(zhí)行時間 System.out.println("Schedule exec time is : " + sf.format(scheduledExecutionTime())); System.out.println("Task is being executed!"); } }, calendar.getTime(), 2000); } }3-4 Timer函數(shù)的綜合應(yīng)用
主要內(nèi)容
通過模擬兩個機(jī)器人的定時行為來把前面所學(xué)的主要函數(shù)給結(jié)合起來,讓大家加深對這些函數(shù)的理解
實現(xiàn)兩個機(jī)器人
第一個機(jī)器人會隔兩秒打印最近一次計劃的時間、執(zhí)行內(nèi)容 第二個機(jī)器人會模擬往桶里倒水,直到桶里的水滿為止
灌水機(jī)器人的執(zhí)行流程
跳舞機(jī)器人的執(zhí)行流程
代碼演示
1.創(chuàng)建跳舞機(jī)器人
package com.myimooc.timer; import java.text.SimpleDateFormat; import java.util.TimerTask; /** * 跳舞機(jī)器人 * Created by ChangComputer on 2017/5/24. */ public class DancingRobot extends TimerTask{ /** * 任務(wù)執(zhí)行 * */ @Override public void run() { // 獲取最近的一次任務(wù)執(zhí)行的時間并將其格式化 SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.print("Schduled exec time is : " + sf.format(scheduledExecutionTime())); System.out.println("Dancing happily!"); } }
2.創(chuàng)建灌水機(jī)器人
package com.myimooc.timer; import java.util.Timer; import java.util.TimerTask; /** * 灌水機(jī)器人 * Created by ChangComputer on 2017/5/24. */ public class WaterRobot extends TimerTask{ private Timer timer; // 桶容量,最大容量為5 private Integer bucketCapacity = 0; public WaterRobot(Timer timer){ this.timer = timer; } @Override public void run() { // 灌水直至桶滿為止 if (this.bucketCapacity < 5) { System.out.println("Add 1L water into the bucket!"); bucketCapacity++; }else{ System.out.println("The number of canceled task in timer is : " + timer.purge()); // 水滿之后就停止執(zhí)行 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); // 等待兩秒鐘,終止timer里面的所有內(nèi)容 try { Thread.sleep(2000L); } catch (InterruptedException e) { e.printStackTrace(); } timer.cancel(); } } }
3.創(chuàng)建執(zhí)行類
package com.myimooc.timer; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Timer; /** * 機(jī)器人執(zhí)行類 * Created by ChangComputer on 2017/5/24. */ public class RobotExecutor { 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 dancingRobot = new DancingRobot(); WaterRobot waterRobot = new WaterRobot(timer); timer.schedule(dancingRobot,calendar.getTime(),2000L); timer.scheduleAtFixedRate(waterRobot,calendar.getTime(),1000L); } }第四章:Timer的缺陷 4-1 Timer的缺陷
Timer天生的兩種缺陷
管理并發(fā)任務(wù)的缺陷
Timer有且僅有一個線程去執(zhí)行定時任務(wù),如果存在多個任務(wù),且任務(wù)時間過長,會導(dǎo)致執(zhí)行效果與預(yù)期不符
當(dāng)任務(wù)拋出異常時的缺陷
如果TimerTask拋出RuntimeException,Timer會停止所有任務(wù)的運(yùn)行
Timer的使用禁區(qū)
對時效性要求較高的多任務(wù)并發(fā)作業(yè) 對復(fù)雜任務(wù)的調(diào)度
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/67126.html
摘要:時間年月日星期一說明本文部分內(nèi)容均來自慕課網(wǎng)。屬性任務(wù)名稱任務(wù)所屬組任務(wù)實現(xiàn)類傳參的作用淺談上是什么當(dāng)調(diào)用一個,就會將傳遞給的方法能通過對象訪問到運(yùn)行時候的環(huán)境以及本身的明細(xì)數(shù)據(jù)。 時間:2017年06月26日星期一說明:本文部分內(nèi)容均來自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com教學(xué)示例源碼:https://github.com/zccodere/s...個人學(xué)習(xí)源碼...
摘要:坦克大戰(zhàn)上簡介上的坦克大戰(zhàn)相信大家都玩過有逃學(xué)玩坦克的可以自己默默的扣一個了我們現(xiàn)在長大了,學(xué)習(xí)游戲開發(fā)了。 寫在前面 上一篇(https://www.tech1024.cn/origi... )說了如何創(chuàng)建項目,并爬去網(wǎng)站內(nèi)容,下面我們說一下如何保存爬去到的數(shù)據(jù) 開始爬取 創(chuàng)建Spider,上一篇我們已經(jīng)創(chuàng)建了ImoocSpider,我們做一下修改,可以連續(xù)下一頁爬取。scrapyD...
時間:2017年10月16日星期一說明:本文部分內(nèi)容均來自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com教學(xué)源碼:無學(xué)習(xí)源碼:https://github.com/zccodere/s... 第一章:課程簡介 1-1 課程介紹 本門課程的主要內(nèi)容 RxJava是什么 RxAndroid是什么 RxJava常用操作符(重點(diǎn)、難點(diǎn)) 怎樣在項目中使用RxJava和RxAndroid 如何學(xué)...
摘要:慕課網(wǎng)消息中間件極速入門與實戰(zhàn)學(xué)習(xí)總結(jié)時間年月日星期三說明本文部分內(nèi)容均來自慕課網(wǎng)。 慕課網(wǎng)《RabbitMQ消息中間件極速入門與實戰(zhàn)》學(xué)習(xí)總結(jié) 時間:2018年09月05日星期三 說明:本文部分內(nèi)容均來自慕課網(wǎng)。@慕課網(wǎng):https://www.imooc.com 教學(xué)源碼:無 學(xué)習(xí)源碼:https://github.com/zccodere/s... 第一章:RabbitM...
摘要:入門篇學(xué)習(xí)總結(jié)時間年月日星期三說明本文部分內(nèi)容均來自慕課網(wǎng)。主要的功能是日志記錄,性能統(tǒng)計,安全控制,事務(wù)處理,異常處理等等。 《Spring入門篇》學(xué)習(xí)總結(jié) 時間:2017年1月18日星期三說明:本文部分內(nèi)容均來自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com教學(xué)示例源碼:https://github.com/zccodere/s...個人學(xué)習(xí)源碼:https://git...
閱讀 4041·2021-11-22 13:53
閱讀 1785·2021-08-25 09:39
閱讀 2495·2019-08-29 18:36
閱讀 1547·2019-08-26 13:35
閱讀 1281·2019-08-26 11:57
閱讀 1769·2019-08-23 15:57
閱讀 882·2019-08-23 14:55
閱讀 1226·2019-08-23 14:51