java-线程-定时器-工具类

    xiaoxiao2021-03-25  85

    汇总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秒,而当前任务已经开始执行了,因此两个任务间存在重叠,需要考虑线程同步;

    参考资料: http://blog.csdn.net/gtuu0123/article/details/6040159

    转载请注明原文地址: https://ju.6miu.com/read-12602.html

    最新回复(0)