1. 程式人生 > >常用的三種定時任務方式

常用的三種定時任務方式

一、直接使用執行緒來實現定時任務
package com.sinosoft.test.Timer;
public class Task1 {
/**
* 普通thread
* 這是最常見的,建立一個thread,然後讓它在while迴圈裡一直執行著,
* 通過sleep方法來達到定時任務的效果。這樣可以快速簡單的實現,程式碼如下:
*/
public static void main(String[] args) {
final long timeInterval = 1000;
Runnable runnable = new Runnable() {
public void run() {
int number = 0;
while (true) {
// ------- code for task to run
System.out.println(“Hello !!”);
//設定結束條件
try {
Thread.sleep(timeInterval);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Thread thread = new Thread(runnable);
thread.start();
}
}

二、使用Timer實現定時任務
package com.sinosoft.test.Timer;
import java.util.Timer;
import java.util.TimerTask;

/**

  • 於第一種方式相比,優勢 1>當啟動和去取消任務時可以控制 2>第一次執行任務時可以指定你想要的delay時間
  • 在實現時,Timer類可以排程任務,TimerTask則是通過在run()方法裡實現具體任務。 Timer例項可以排程多工,它是執行緒安全的。
  • 當Timer的構造器被呼叫時,它建立了一個執行緒,這個執行緒可以用來排程任務。 下面是程式碼:
    */
    public class Task2 {
    public static void main(String[] args) {
    final Timer timer = new Timer();
    TimerTask task = new TimerTask() {
    @Override
    public void run() {
    // task to run goes here
    System.out.println(“Hello !!!”);
    timer.cancel();//任務完成,結束執行緒。這個例子是呼叫cancel方法結束執行緒。
    }
    };
    long delay = 1000;
    long intevalPeriod = 1 * 2000;
    // schedules the task to be run in an interval
    timer.scheduleAtFixedRate(task, delay, intevalPeriod);
    }
    }

注意:schedule VS. scheduleAtFixedRate
這兩個方法都是任務排程方法,他們之間區別是,schedule會保證任務的間隔是按照定義的period引數嚴格執行的,如果某一次排程時間比較長,那麼後面的時間會順延,保證排程間隔都是period,而scheduleAtFixedRate是嚴格按照排程時間來的,如果某次排程時間太長了,那麼會通過縮短間隔的方式保證下一次排程在預定時間執行。舉個栗子:你每個3秒排程一次,那麼正常就是0,3,6,9s這樣的時間,如果第二次排程花了2s的時間,如果是schedule,就會變成0,3+2,8,11這樣的時間,保證間隔,而scheduleAtFixedRate就會變成0,3+2,6,9,壓縮間隔,保證排程時間。
三、使用ScheduledExecutorService實現定時任務
package com.sinosoft.test.Timer;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**

  • ScheduledExecutorService是從Java SE5的java.util.concurrent裡,做為併發工具類被引進的,這是最理想的定時任務實現方式。
  • 相比於上兩個方法,它有以下好處:
  • 1>相比於Timer的單執行緒,它是通過執行緒池的方式來執行任務的
  • 2>可以很靈活的去設定第一次執行任務delay時間
  • 3>提供了良好的約定,以便設定執行的時間間隔
  • 下面是實現程式碼,我們通過ScheduledExecutorService#scheduleAtFixedRate展示這個例子,通過程式碼裡引數的控制,首次執行加了delay時間。
    */
    public class Task3 {
    public static void main(String[] args) {
    Runnable runnable = new Runnable() {
    public void run() {
    // task to run goes here
    System.out.println(“Hello !!”);
    }
    };
    ScheduledExecutorService service = Executors
    .newSingleThreadScheduledExecutor();
    // 第二個引數為首次執行的延時時間,第三個引數為定時執行的間隔時間,單位為秒
    service.scheduleAtFixedRate(runnable, 2, 3, TimeUnit.SECONDS);
    }
    }