详解java定时任务
详解java定时任务:
第一种:利用Tiker和TimerTask
指定延迟时间执行定时任务
package com.huohg.Quartz; import java.util.Timer; import java.util.TimerTask; public class TimerTest01 { Timer timer; public TimerTest01(int time){ timer = new Timer(); timer.schedule(new TimerTaskTest01(), time * 1000); } public static void main(String[] args) { System.out.println("timer begin...."); new TimerTest01(3); } } class TimerTaskTest01 extends TimerTask{ public void run() { System.out.println("Time's up!!!!"); } }
运行结果:
在指定时间执行定时任务
package com.huohg.Quartz; import java.util.Calendar; import java.util.Date; import java.util.Timer; import java.util.TimerTask; /** * 在指定时间执行定时任务 * 当时间到达16:21:00时就会执行该线程任务,当然大于该时间也会执行!!执行结果为: * */ public class TimerTest02 { Timer timer; public TimerTest02(){ Date time = getTime(); System.out.println("指定时间time=" + time); timer = new Timer(); timer.schedule(new TimerTaskTest02(), time); } public Date getTime(){ Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.HOUR_OF_DAY, 16); calendar.set(Calendar.MINUTE, 21); calendar.set(Calendar.SECOND, 00); Date time = calendar.getTime(); return time; } public static void main(String[] args) { new TimerTest02(); } } class TimerTaskTest02 extends TimerTask{ @Override public void run() { System.out.println("指定时间执行线程任务..."); } }
运行结果:
在延迟指定时间后以指定的间隔时间循环执行定时任务
package com.huohg.Quartz; import java.util.Date; import java.util.Timer; import java.util.TimerTask; /** * 在延迟指定时间后以指定的间隔时间循环执行定时任务 * */ public class TimerTest03 { Timer timer; public TimerTest03(){ timer = new Timer(); timer.schedule(new TimerTaskTest03(), 1000, 2000); } public static void main(String[] args) { new TimerTest03(); } } class TimerTaskTest03 extends TimerTask{ @Override public void run() { Date date = new Date(this.scheduledExecutionTime()); System.out.println("本次执行该线程的时间为:" + date); } }
总结:
Timer计时器可以定时(指定时间执行任务)、延迟(延迟5秒执行任务)、周期性地执行任务(每隔个1秒执行任务),但是,Timer存在一些缺陷。首先Timer对调度的支持是基于绝对时间的,而不是相对时间,所以它对系统时间的改变非常敏感。其次Timer线程是不会捕获异常的,如果TimerTask抛出的了未检查异常则会导致Timer线程终止,同时Timer也不会重新恢复线程的执行,他会错误的认为整个Timer线程都会取消。同时,已经被安排单尚未执行的TimerTask也不会再执行了,新的任务也不能被调度。故如果TimerTask抛出未检查的异常,Timer将会产生无法预料的行为。
解决问题:
对于Timer的缺陷,我们可以考虑 ScheduledThreadPoolExecutor 来替代。Timer是基于绝对时间的,对系统时间比较敏感,而ScheduledThreadPoolExecutor 则是基于相对时间;Timer是内部是单一线程,而ScheduledThreadPoolExecutor内部是个线程池,所以可以支持多个任务并发执行。
package com.huohg.Quartz; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /* * 替换 Timer定时任务 * ScheduledExecutorService * * **/ public class ScheduledExecutorTest { private ScheduledExecutorService scheduExec; public long start; ScheduledExecutorTest(){ this.scheduExec = Executors.newScheduledThreadPool(2); this.start = System.currentTimeMillis(); } public void timerOne(){ scheduExec.schedule(new Runnable() { public void run() { throw new RuntimeException(); } },1000,TimeUnit.MILLISECONDS); } public void timerTwo(){ scheduExec.scheduleAtFixedRate(new Runnable() { public void run() { System.out.println("timerTwo invoked ....."); } },2000,500,TimeUnit.MILLISECONDS); } public static void main(String[] args) { ScheduledExecutorTest test = new ScheduledExecutorTest(); test.timerOne(); test.timerTwo(); } }