http://blog.csdn.net/xyang81/article/details/7425943
在日常工作中,定時進行任務調度的業務隨處可見,比如:定時清理系統的臨時文件、有新的活動定時向用戶發送電子郵件、定時檢查系統是否需要更新、定時發送短信等業務。在Java中由兩個類完成定時任務的調度,分別爲:java.util.Timer和java.util.TimerTask
創建一個定時任務的步聚:
1、創建一個定時器(Timer)對象
2、調用該對象的
或schedule(TimerTask task, long delay, long period)
scheduleAtFixedRate(TimerTask task,
long delay, long period)
方法
任務調度方法參數說明:
task:表示要執行的具體任務
:表示任務創建完成後,第一次什麼時候開始執行該任務,以毫秒爲單位delay
period:表示第一次執行完任務後,後續重複執行該任務的時間間隔是多長,以毫秒爲單位
schedule方法與
scheduleAtFixedRate方法的區別:
方法 | 任務執行時間 | 當任務執行時間大於間隔時間時 |
schedule | 上次任務的結束時間+時間間隔 | 阻塞式,任務會延後,等待前面的任務執行完,再執行延務後的任務 |
scheduleAtFixedRate | 上次任務的執行時間+時間間隔 | 任務不會延後,但要考慮多線程併發的問題。因爲當一個任務還沒執行完時,下一個時間間隔任務又會啓動,執行相同的任務 |
注意:每啓動一個新任務,就會啓動一個新的線程!
- package taskschedule;
- import java.text.SimpleDateFormat;
- import java.util.Calendar;
- import java.util.Timer;
- import java.util.TimerTask;
- /*
- * 定時器
- *
- * schedule():下一次任務的執行時間,等於上一次任務的結束時間+時間間隔
- *
- * scheduleAtFixedRate():下一次任務的執行時間,等於上一次任務的開始時間+時間間隔
- *
- * 當執行任務的時間大於時間間隔時:
- * schedule任務會延後。
- * scheduleAtFixedRate任務不會延後,仍然在時間間隔內執行,存在併發性,要考慮線程同步的問題
- */
- public class TimerTest {
- private static int count = 0;
- public static void main(String[] args) {
- task_1();
- //task_2();
- //task_3();
- //task_4();
- //主線程
- while(true) {
- System.out.println(Calendar.getInstance().get(Calendar.SECOND));
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- //任務1:第一次延遲3秒後啓動任務,後續每隔2秒啓動一次任務
- private static void task_1() {
- new Timer().schedule(new TimerTask(){
- @Override
- public void run() {
- System.out.println(Thread.currentThread().getName() + "定時任務已啓動!");
- }}, 3000,2000);
- }
- //任務2:交互執行,方式1:第一次延遲2秒後啓動任務,後續每隔在3秒和6秒之間切換啓動任務
- private static void task_2() {
- class MyTimerTask extends TimerTask {
- @Override
- public void run() {
- count = (count+1)%2;
- System.out.println(Thread.currentThread().getName() + "定時任務已啓動!");
- new Timer().schedule(new MyTimerTask(), 3000 + 3000 * count); //循環調用
- }
- }
- new Timer().schedule(new MyTimerTask(), 2000); //2秒後啓動定時器
- }
- //任務3:交互執行,方式2:第一次延遲2秒後啓動任務,後續每隔在3秒和6秒之間切換啓動任務
- public static void task_3() {
- new Timer().schedule(new MyTimerTaskA(), 300);
- }
- //任務4:演示scheduleAtFixedRate方法,第一次延遲2秒後啓動任務,後續每隔3秒後啓動任務,但任務執行時間大於等於6秒
- public static void task_4() {
- TimerTask task = new TimerTask(){
- @Override
- public void run() {
- System.out.println("execute task:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Calendar.getInstance().getTime()));
- try {
- Thread.sleep(6000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println(Thread.currentThread().getName() + "定時任務已啓動!");
- }
- };
- new Timer().scheduleAtFixedRate(task, 2000, 3000);
- }
- }
- //描述2個任務切換啓動
- class MyTimerTaskA extends TimerTask {
- @Override
- public void run() {
- System.out.println(Thread.currentThread().getName() + "任務已啓動!");
- new Timer().schedule(new MyTimerTaskB(),2000);
- }
- }
- class MyTimerTaskB extends TimerTask {
- @Override
- public void run() {
- System.out.println(Thread.currentThread().getName() + "任務已啓動!");
- new Timer().schedule(new MyTimerTaskA(), 4000);
- }
- }
任務執行結果:
任務1:
任務2:
任務3:
任務4:
但JDK提供的定時器任務功能有限,不能完成一些複雜的業務,比如:要每年單月的每週星期三的下午5點10分要執行一個任務,JDK則處理不了。不過不要擔心,市面上已經有開源的任務調度框架:Quartz,官網:http://www.quartz-scheduler.org/