Java定时执行任务

时间:2022-02-04 21:10:12

Java中定时执行某任务,最常见的恐怕就是用Java API中的Timer定时器了.除此之外,常见的还有基于线程模式的以及自Java1.5开始提供的新API ScheduledExecutorService接口.下面分别介绍:

Timer定时器

Timer定时器介绍

Timer主要是用来定时执行某个任务. 常见的方法包含

方法名 方法描述
schedule(TimerTask task, Date time) 在time指定的时间时候执行task任务
schedule(TimerTask task, Date firstTime, long period) 在firstTime指定的时间时候开始执行task任务,之后每隔period时间后执行task任务
schedule(TimerTask task, long delay) 从程序执行时间开始,延迟delay时间后执行task任务
schedule(TimerTask task, long delay, long period) 从程序执行开始,延迟delay时间后执行task任务,之后每隔period时间后执行task任务
scheduleAtFixedRate(TimerTask task, Date firstTime, long period) 在firstTime指定的时间时候开始执行task任务,之后每隔period时间后执行task任务
scheduleAtFixedRate(TimerTask task, long delay, long period) 从程序执行开始,延迟delay时间后执行task任务,之后每隔period时间后执行task任务

schedule与scheduleAtFixedRate的区别

在Timer的常用方法中,有两组方法没有明确说明其区别,分别为schedule(TimerTask task, Date firstTime, long period)和scheduleAtFixedRate(TimerTask task, Date firstTime, long period),另一组为schedule(TimerTask task, long delay, long period)和scheduleAtFixedRate(TimerTask task, long delay, long period).
先看程序:

public static void testSchedule() {
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date d1 = null;
try {
d1 = sdf.parse("2016/2/19 11:05:00");
Timer t = new Timer();
t.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("Schedule Time is " + sdf.format(new Date(System.currentTimeMillis())));
}
}, d1, 5 * 1000);
} catch (ParseException e) {
e.printStackTrace();
}
}

public static void testScheduleFixRate() {
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date d1 = null;
try {
d1 = sdf.parse("2016/2/19 11:05:00");
Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
int i = 1;
@Override
public void run() {
System.out.println(i + ": ScheduleFixRate Time is " + sdf.format(new Date(System.currentTimeMillis())));
i++;
}
}, d1, 5 * 1000);
} catch (ParseException e) {
e.printStackTrace();
}
}

结果发现, 若当前时间早于2016/2/19 11:05:00时,结果是一样的;而当当前时间晚于2016/2/19 11:05:00时,scheduleAtFixedRate方法会将从firstTime到当前时间缺少的执行次数补回来,而后按照period时间间隔执行,而schedule方法会在当前时间执行第一次,之后按照period时间间隔执行.

基于多线程的延时

public static void threadDelay () {
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Thread thread = new Thread(new Runnable() {
int i = 0;
@Override
public void run() {
while (true) {
System.out.println(i + ": threadDelay Time is " + sdf.format(new Date(System.currentTimeMillis())));
i++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});

thread.start();
}

ScheduledExecutorService接口

ScheduledExecutorService接口特别适用于并发程序的执行.

public static void scheduledExecutor() {
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);

scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
int i = 0;
@Override
public void run() {
i++;
System.out.println(i + ": scheduledExecutor time is " + sdf.format(new Date()));
}
}, 0, 1, TimeUnit.SECONDS);
}