Timer对调度的支持是基于绝对时间,而不是相对时间。而ScheduledExecutorService只支持相对时间。
ScheduledExecutorService接口在ExecuteService基础上,提供了按间安排执行任务的功能。
1.Timer管理延时任务的缺陷
因为Timer在执行定时任务时只会创建一个线程,所以如果存在多个任务,且任务过长,超过两个任务时间间隔,会发生一些缺陷。
public class TimerTest
{
private static long start;
public static void main(String[] args) throws Exception
{
TimerTask task1 = new TimerTask()
{
@Override
public void run()
{
System.out.println("task1 invoked ! "
+ (System.currentTimeMillis() - start));
try
{
Thread.sleep(3000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
};
TimerTask task2 = new TimerTask()
{
@Override
public void run()
{
System.out.println("task2 invoked ! "
+ (System.currentTimeMillis() - start));
}
};
Timer timer = new Timer();
start = System.currentTimeMillis();
timer.schedule(task1, 1000);
timer.schedule(task2, 3000);
}
}
由于Timre内部是一个线程,而任务1所需的时间超过了两个任务间的间隔,所以任务2的执行和预期不一样。
而ScheduledThreadPool内部是个线程池,所以可以支持多个任务并发执行。
2.Timer当任务抛出异常时的缺陷
如果TimerTask抛出RuntimerExceptin,Timer会停止所有任务的运行。
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class ScheduledThreadPoolDemo01
{
public static void main(String[] args) throws InterruptedException
{
final TimerTask task1 = new TimerTask()
{
@Override
public void run()
{
throw new RuntimeException();
}
};
final TimerTask task2 = new TimerTask()
{
@Override
public void run()
{
System.out.println("task2 invoked!");
}
};
Timer timer = new Timer();
timer.schedule(task1, 100);
timer.scheduleAtFixedRate(task2, new Date(), 1000);
}
}
但是ScheduledExecutorService可以保证,task1出现异常时,不影响task2的运行。
3.Timer执行周其任务时依赖系统时间
Timer执行周期任务时依赖系统时间,如果当前系统时间发生变化会出现一些执行上的变化,ScheduledExecutorService基于时间的延迟。
最后欢迎大家访问我的个人网站:1024s