Java定时器_ScheduledThreadPoolExecutorjava
延迟任务:在xx秒后执行该任务算法
周期任务:每xx秒执行一次任务ide
Timer存在一些缺陷,应该考虑使用ScheduleThreadPoolExecutor 来代替他。函数
能够经过ScheduleThreadPoolExecutor 的构造函数或Executors 的newScheduleThreadPool工厂方法来建立该类的对象。spa
Timer在执行全部定时任务时只会建立一个线程。若是某个任务执行时间过长,那么将破坏其余TimerTask的定时精确性。线程
Timer另外一个问题是若是TimeTask抛出了一个未检查的异常,那么Timer将表现出槽糕的行为。Timer线程并不捕获异常,所以当TimerTask抛出未检查的异常时将终止定时线程。这种状况下,Timer也不会恢复线程的执行,而是会错误地认为整个Timer都消失了。所以,已经被调度但还没有执行的TimerTask将不会再执行,新的任务也不会被调度。这就是线程泄漏。code
以下代码片断对象
package com.usoft.schedule; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** * @author: Lenovo(2015-08-13 23:54) */ public class ScheduledTest { public static void main(String args[]) throws ExecutionException, InterruptedException { ScheduledExecutorService schedule = Executors .newScheduledThreadPool(2); /** * 延迟1秒执行任务一次 */ schedule.schedule(new Runnable() { @Override public void run() { System.out.println("hello world runnable"); } }, 1000, TimeUnit.MILLISECONDS); /** * 延迟2秒执行任务一次 */ Future result = schedule.schedule(new Callable<String>() { @Override public String call() throws Exception { return "hello world callable"; } }, 2000, TimeUnit.MILLISECONDS); System.out.println(result.get()); // 以固定的频率来周期的执行任务 schedule.scheduleAtFixedRate(new Runnable() { @Override public void run() { System.out.println("定时周期任务执行"); } }, 1000, 2000, TimeUnit.MILLISECONDS); // 以固定的延迟来周期的执行任务 schedule.scheduleWithFixedDelay(new Runnable() { @Override public void run() { System.out.println("定时周期任务执行"); } }, 1000, 3000, TimeUnit.MILLISECONDS); // 关闭定时和周期任务的执行 Thread.sleep(1000 * 10); schedule.shutdown();//平缓的关闭 System.out.println("pool shutdown:" + schedule.isShutdown()); while (!schedule.isTerminated()) { schedule.awaitTermination(1, TimeUnit.SECONDS); } } }
要说定时任务,其实都是用延迟任务和周期任务来实现定时的。继承
好比说,我要在天天的中午12点启动一个定时任务,就要根据当前程序的启动时间来算出延迟多长时间来执行这个任务,而且是周期的执行,有一个固定的算法来算出延迟的时长。get
package com.usoft.schedule; import java.util.Calendar; public class Main23 { private static final int period = 1000 * 60; //秒 private static final int one_day_millseconds = 24 * 60 * 60 * 1000; public static void main(String args[]) { int dayOfHour = 0; // 24h 制 int minute = 0; int second = 0; long delay; //首次执行任务的延迟 Calendar c = Calendar.getInstance(); long currentTime = c.getTimeInMillis(); c.set(Calendar.HOUR_OF_DAY, dayOfHour); c.set(Calendar.MINUTE, minute); c.set(Calendar.SECOND, second); long executeTime = c.getTimeInMillis(); delay = executeTime - currentTime < 0 ? (executeTime - currentTime + one_day_millseconds) : (executeTime - currentTime); System.out.println("DelayTimeInMillis =" + delay); System.out.println("DelayTimeInSecond =" + delay / 1000); System.out.println("DelayTimeInHour =" + delay / (1000 * 60 * 60)); } }
===============END===============