Java中定時執行某任務,最常見的恐怕就是用Java API中的Timer定時器了.除此之外,常見的還有基於線程模式的以及自Java1.5開始提供的新API ScheduledExecutorService介面.下面分別介紹: Timer定時器 Timer定時器介紹
Timer主要是用來定時執行某個任務. 常見的方法包含
| 方法名 |
方法描述 |
| schedule(TimerTask task, Date time) |
在time指定的時間時候執行task任務 |
| schedule(TimerTask task, Date firstTime, long period) |
在firstTime指定的時間時候開始執行task任務,之後每隔period時間後執行task任務 |
| schedule(TimerTask task, long delay) |
從程式執行時間開始,延遲delay時間後執行task任務 |
| schedule(TimerTask task, long delay, long period) |
從程式執行開始,延遲delay時間後執行task任務,之後每隔period時間後執行task任務 |
| scheduleAtFixedRate(TimerTask task, Date firstTime, long period) |
在firstTime指定的時間時候開始執行task任務,之後每隔period時間後執行task任務 |
| scheduleAtFixedRate(TimerTask task, long delay, long period) |
從程式執行開始,延遲delay時間後執行task任務,之後每隔period時間後執行task任務 |
schedule與scheduleAtFixedRate的區別
在Timer的常用方法中,有兩組方法沒有明確說明其區別,分別為schedule(TimerTask task, Date firstTime, long period)和scheduleAtFixedRate(TimerTask task, Date firstTime, long period),另一組為schedule(TimerTask task, long delay, long period)和scheduleAtFixedRate(TimerTask task, long delay, long period).
先看程式:
public static void testSchedule() { final SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); Date d1 = null; try { d1 = sdf.parse("2016/2/19 11:05:00"); Timer t = new Timer(); t.schedule(new TimerTask() { @Override public void run() { System.out.println("Schedule Time is " + sdf.format(new Date(System.currentTimeMillis()))); } }, d1, 5 * 1000); } catch (ParseException e) { e.printStackTrace(); }}public static void testScheduleFixRate() { final SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); Date d1 = null; try { d1 = sdf.parse("2016/2/19 11:05:00"); Timer t = new Timer(); t.scheduleAtFixedRate(new TimerTask() { int i = 1; @Override public void run() { System.out.println(i + ": ScheduleFixRate Time is " + sdf.format(new Date(System.currentTimeMillis()))); i++; } }, d1, 5 * 1000); } catch (ParseException e) { e.printStackTrace(); }}
結果發現, 若目前時間早於2016/2/19 11:05:00時,結果是一樣的;而噹噹前時間晚於2016/2/19 11:05:00時,scheduleAtFixedRate方法會將從firstTime到目前時間缺少的執行次數補回來,而後按照period時間間隔執行,而schedule方法會在目前時間執行第一次,之後按照period時間間隔執行. 基於多線程的延時
public static void threadDelay () { final SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); Thread thread = new Thread(new Runnable() { int i = 0; @Override public void run() { while (true) { System.out.println(i + ": threadDelay Time is " + sdf.format(new Date(System.currentTimeMillis()))); i++; try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }); thread.start();}
ScheduledExecutorService介面
ScheduledExecutorService介面特別適用於並發程式的執行.
public static void scheduledExecutor() { final SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1); scheduledExecutorService.scheduleAtFixedRate(new Runnable() { int i = 0; @Override public void run() { i++; System.out.println(i + ": scheduledExecutor time is " + sdf.format(new Date())); } }, 0, 1, TimeUnit.SECONDS); }