汇总JDK定时器的实现
package thread.timetask;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class TimeTaskUtil {
/**
* 优点:
* 1>当启动和去取消任务时可以控制
* 2>第一次执行任务时可以指定你想要的delay时间
* Timer实例可以调度多任务,它是线程安全的。
* 当Timer的构造器被调用时,它创建了一个线程,这个线程可以用来调度任务。
*
* @param task task to be scheduled.
* @param delay delay in milliseconds before task is to be executed.
* @param intevalPeriod time in milliseconds between successive task executions.
* 1000 * 60 * 60 * 24 设定将延时每天固定执行
*/
public static Timer runOne(TimerTask task, long delay, long intevalPeriod) {
Timer timer = new Timer();
timer.schedule(task,delay,intevalPeriod);
// timer.scheduleAtFixedRate(task, delay, intevalPeriod);
return timer;
}
/**
* 在指定的时间开始执行
*
* @param calendar * Calendar calendar = Calendar.getInstance();
* calendar.set(Calendar.HOUR_OF_DAY, hour); // 控制时
* calendar.set(Calendar.MINUTE, min); // 控制分
* calendar.set(Calendar.SECOND, second); // 控制秒
* ...
* @param timerTask task to be scheduled.
* @param period time in milliseconds between successive task executions.
* 1000 * 60 * 60 * 24 设定将延时每天固定执行
*/
public static Timer runTwo(Calendar calendar, TimerTask timerTask, long period) {
Date time = calendar.getTime();
Timer timer = new Timer();
timer.schedule(timerTask,time,period);
// timer.scheduleAtFixedRate(timerTask, time, period);
return timer;
}
/**
* ScheduledExecutorService是从Java SE5的java.util.concurrent里,做为并发工具类被引进的,
* 1>相比于Timer的单线程,它是通过线程池的方式来执行任务的
* 2>可以很灵活的去设定第一次执行任务delay时间
* 3>提供了良好的约定,以便设定执行的时间间隔
*
* @param runnable 运行的任务
* @param initialDelay 首次执行的延时时间
* @param period 定时执行的间隔时间
* @param unit 时间单位
*/
public static ScheduledExecutorService runThree(Runnable runnable, long initialDelay,
long period,
TimeUnit unit) {
ScheduledExecutorService service = Executors
.newSingleThreadScheduledExecutor();
service.schedule(runnable,period,unit);
// service.scheduleAtFixedRate(runnable, initialDelay, period, unit);
return service;
}
public static void main(String[] args) {
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
System.out.println(System.currentTimeMillis());
}
};
// runOne(timerTask, 1000, 1000);
Calendar calendar = Calendar.getInstance();
Timer timer = runTwo(calendar, timerTask, 1000);
//将任务队列中的全部任务清空.
// timer.cancel();
// Runnable task = new Runnable() {
// @Override
// public void run() {
// System.out.println(System.currentTimeMillis());
// }
// };
// runThree(task, 1, 5, TimeUnit.SECONDS);
}
}
说下schedule和scheduleAtFixedRate的区别:
(1)schedule方法:“fixed-delay”;
如果第一次执行时间被delay了,随后的执行时间按照上一次实际执行完成的时间点进行计算;
下一次的执行时间点=上一次程序执行完成的时间点+间隔时间;
下一次执行时间相对于上一次实际执行完成的时间点,因此执行时间会不断延后;
(2)scheduleAtFixedRate方法:“fixed-rate”;
如果第一次执行时间被delay了,随后的执行时间按照 上一次开始的 时间点 进行计算,并且为了”catch up”会多次执行任务,TimerTask中的执行体需要考虑同步;
下一次执行时间相对于上一次开始的 时间点 ,因此执行时间不会延后,存在并发性;
下一次的执行时间点=上一次程序开始执行的时间点+间隔时间 ;并且因为前一个任务要执行6秒,而当前任务已经开始执行了,因此两个任务间存在重叠,需要考虑线程同步;