首先咱們先明確一下什麼是定時任務調度?java
基於給定的時間點,給定的時間間隔或者給定的執行次數自動執行的任務。api
Java中定時任務調動工具備倆:Timer 、Quartz多線程
區別:併發
出身不一樣:Timer由jdk直接提供,不需jar包支持;Quartz需引入jar包。ide
能力不一樣:Timer簡單定時任務;Quartz時間控制功能更強大。函數
底層機制:Timer只有一個後臺線程執行;Quartz是多線程執行任務。工具
讓咱們看下官方文檔api(JDK1.8)this
可能有的小夥伴英語水平不太好,那讓咱們看下中文版吧:spa
那麼咱們能夠概括Timer的定義:有且僅有一個後臺線程對多個業務線程進行定時定頻率的調度線程
主要構件:
Timer工具類詳解:
package com.leo.timer; import java.util.TimerTask; public class MyTimerTask extends TimerTask { private String name; public MyTimerTask(String inputName){ name=inputName; } @Override public void run() { //打印當前name的內容 System.out.println("Current exec name is"+name); } public String getName() { return name; } public void setName(String name) { this.name = name; } }
package com.leo.timer; import java.util.Timer; public class MyTimer { public static void main(String[] args){ //1.建立一個timer實例 Timer timer=new Timer(); //2.建立一個MyTimerTask實例 MyTimerTask myTimerTask=new MyTimerTask("No.1"); //3.經過timer定時頻率調用myTImerTask的業務邏輯 // 既第一次執行是在當前時間的兩秒以後,以後每隔一秒鐘執行一次 timer.schedule(myTimerTask,2000L,1000L); } }
控制檯打印顯示:
做用:在時間等於或超過time的時候執行且僅執行一次task
參數: task-所要安排的任務
time-首次執行任務的時間
period-執行一次task的時間間隔,單位是毫秒
參數: task-所要安排的任務
delay-執行任務前的延遲時間,單位是毫秒
做用: 等待delay毫秒後執行且僅執行一次task
參數: task-所要安排的任務
delay-執行任務前的延遲時間,單位是毫秒
period-執行一次task的時間間隔,單位是毫秒
做用: 等待delay毫秒後執行且僅執行一次task,以後每隔period毫秒重複執行一次task
具體代碼以下:
定時任務類:
package com.leo.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() { //打印當前name的內容 System.out.println("Current exec name is "+name); //以yyyy-MM-dd HH:mm:ss的格式打印當前執行時間 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())); } public String getName() { return name; } public void setName(String name) { this.name = name; } }
四中啓動類:
package com.leo.timer; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Timer; public class MyTimer { public static void main(String[] args){ //一.建立一個timer實例 Timer timer=new Timer(); //二.建立一個MyTimerTask實例 MyTimerTask myTimerTask=new MyTimerTask("No.1"); //三.經過timer定時頻率調用myTImerTask的業務邏輯 // 既第一次執行是在當前時間的兩秒以後,以後每隔一秒鐘執行一次 //timer.schedule(myTimerTask,2000L,1000L); /** * 獲取當前時間,並設置成距離當前時間三秒以後的時間 * 若是當前時間是2017-10-21 23:59:57 * 則設置後的時間則爲2017-10-22 00:00:00 */ Calendar calendar=Calendar.getInstance(); SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println(sf.format(calendar.getTime())); calendar.add(Calendar.SECOND,3); /** * 1. schedule(task,time) * 在時間等於或超過time的時候執行且僅執行一次task * 如在2017-10-22 00:00:00 執行一次task:打印任務的名字 */ //myTimerTask.setName("schedule1"); //timer.schedule(myTimerTask,calendar.getTime()); /** * 2. schedule(task,time,period) * 時間等於或超過time時首次執行task * 以後每隔period毫秒重複執行一次task * 如在2017-10-22 00:00:00 第一次執行task:打印任務的名字 * 以後每隔兩秒執行一次task */ //myTimerTask.setName("schedule2"); //timer.schedule(myTimerTask,calendar.getTime(),2000); /** * 3. schedule(task,delay) * 等待delay毫秒後執行且僅執行一次task * 如如今是2017-10-22 00:00:00 * 則在2017-10-22 00:00:01執行一次task::打印任務的名字 */ //myTimerTask.setName("schedule3"); //timer.schedule(myTimerTask,1000); /** * 4. schedule(task,delay,period) * 等待delay毫秒後首次執行task * 如如今是2017-10-22 00:00:00 * 則在2017-10-22 00:00:01執行一次task::打印任務的名字 * 以後每隔兩秒執行一次task */ myTimerTask.setName("schedule4"); timer.schedule(myTimerTask,calendar.getTime(),2000); } }
參數: task-所要安排的任務
time-首次執行任務的時間
period-執行一次task的時間間隔,單位是毫秒
做用: 時間等於或超過time時首次執行task,以後每隔period毫秒重複執行一次task(和schedule的第二種用法是同樣的)
參數: task-所要安排的任務
delay-執行任務前的延遲時間,單位是毫秒
period-執行一次task的時間間隔,單位是毫秒
做用: 等待delay毫秒後執行且僅執行一次task,以後每隔period毫秒重複執行一次task(和schedule的第四種用法是同樣的)
代碼:
//----------------scheduleAtFixedRate的用法------------------------------- /** * 1 . scheduleAtFixedRate(task,time,period) * 時間等於或超過time時首次執行task * 以後每隔period毫秒重複執行一次task * 如在2017-10-22 00:00:00 第一次執行task:打印任務的名字 * 以後每隔兩秒執行一次task */ //myTimerTask.setName("scheduleAtFixedRate1"); //timer.scheduleAtFixedRate(myTimerTask,calendar.getTime(),2000); /** * 2. scheduleAtFixedRate(task,delay,period) * 等待delay毫秒後首次執行task * 如如今是2017-10-22 00:00:00 * 則在2017-10-22 00:00:01執行一次task::打印任務的名字 * 以後每隔兩秒執行一次task */ myTimerTask.setName("scheduleAtFixedRate2"); timer.scheduleAtFixedRate(myTimerTask,3000,2000);
咱們先來看Timer的其餘重要函數,下一標題再具體講解schedule和schedulAtFixedRate兩者的不一樣
cancel:
做用:取消當前TimerTask裏的任務
@Override public void run() { if (count<3){ //打印當前name的內容 System.out.println("Current exec name is "+name); //以yyyy-MM-dd HH:mm:ss的格式打印當前執行時間 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())); count++; }else { cancel(); System.out.println("Task cancel"); } }
scheduledExecutionTime():
做用:返回此任務最近實際執行的已安排執行的時間
cancel():
做用:終止此計時器,丟棄全部當前已安排的任務
purge():
做用:今後計時器的任務隊列中移除所要已取消的任務
返回值:從隊列中移除的任務數
"fixed-delay"若是第一次執行時間被delay了,隨後的執行時間按上一次實際執行完成的時間點進行計算
console:
"fixed-rate"若是第一次執行時間被delay了,隨後的執行時間按上一次實際執行完成的時間點進行計算,而且爲了遇上進度會屢次執行任務,所以TimerTask中的執行體須要考慮同步
console:
下一次執行時間相對於上一次實際執行完成的時間點,所以執行時間會不斷延後
console:
下一次執行時間相對於上一次開始的時間點,所以執行的時間不會延後,所以存在併發性
console:
Timer有且僅有一個線程去執行定時任務,若是存在多個定時任務,且任務時間過長,會致使執行效果與預期不符
console:
一樣scheduleAtFixedRate也不能解決併發問題:
若是TimerTask拋出RuntimeException,Timer會中止全部任務的執行
1.對時效性要求較高的多任務併發做業
2.對複雜的任務的調度
若是想要知足以上功能,需用到Quartz