定时任务Java实现的几种基本方法。
方法一:Thread
是我们最容易想到的,利用while循环,在其中加入sleep方法来实现定时功能。具体代码实现如下
代码示例:
public class TestTimeOrder {
public static void main(String[] args) {
final long timeInterval = 3000;
Runnable runnable = new Runnable() {
@Override
public void run() {
while (true) {
System.out.println(Thread.currentThread().getName() + " 定时间隔3秒");
try {
Thread.sleep(timeInterval);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Thread thread = new Thread(runnable);
thread.start();
}
}
方法二:Timer
考虑利用Timer类来调度任务,Timer实例可以调度多个任务,且是线程安全的。TimerTask在run方法中实现具体的任务要求。
该方法可以在第一次执行任务时设置延迟时间;且可以控制启动和取消任务。
注意:
使用 Timer 实现任务调度的核心类是 Timer 和 TimerTask。其中 Timer 负责设定 TimerTask 的起始与间隔执行时间。使用者只需要创建一个 TimerTask 的继承类,实现自己的 run 方法,然后将其丢给 Timer 去执行即可。Timer 的设计核心是一个 TaskList 和一个 TaskThread。Timer 将接收到的任务丢到自己的 TaskList 中,TaskList 按照 Task 的最初执行时间进行排序。TimerThread 在创建 Timer 时会启动成为一个守护线程。这个线程会轮询所有任务,找到一个最近要执行的任务,然后休眠,当到达最近要执行任务的开始时间点,TimerThread 被唤醒并执行该任务。之后 TimerThread 更新最近一个要执行的任务,继续休眠。
Timer 的优点在于简单易用,但由于所有任务都是由同一个线程来调度,因此所有任务都是串行执行的,同一时间只能有一个任务在执行,前一个任务的延迟或异常都将会影响到之后的任务(这点需要注意)。
代码示例:
public class TestTimeOrder {
public static void main(String[] args) {
TimerTask task = new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " 定时间隔3秒");
}
};
Timer t = new Timer();
long delay = 1000;
long intevalTime = 3000;
t.scheduleAtFixedRate(task, delay, intevalTime);
// t.schedule(task,delay);
}
}
方法三(也是最推荐的用法):线程池
该方法是通过线程池来执行任务实现的,主要是通过ScheduledExecutorService#scheduleAtFixedRate来实现任务运行和定时控制;好处是可以灵活设定第一次执行任务的delay时间以及提供了约定便于设定执行的时间间隔。相比于方法二,Timer是单线程的,该方法是通过线程池技术来实现。可以仔细研究下ScheduledExecutorService的用法。
其设计思想是,每一个被调度的任务都会由线程池中一个线程去执行,因此任务是并发执行的,相互之间不会受到干扰。需 要注意的是,只有当任务的执行时间到来时,ScheduedExecutor 才会真正启动一个线程,其余时间 ScheduledExecutor 都是在轮询任务的状态。
ScheduledExecutorService 中两种最常用的调度方法 ScheduleAtFixedRate 和 ScheduleWithFixedDelay。ScheduleAtFixedRate 每次执行时间为上一次任务开始起向后推一个时间间隔,即每次执行时间为 :initialDelay
, initialDelay+period
, initialDelay+2*period
, … ScheduleWithFixedDelay每次执行时间为上一次任务结束起向后推一个时间间隔,即每次执行时间为:initialDelay
, initialDelay+executeTime+delay
, initialDelay+2*executeTime+2*delay
。由此可见,ScheduleAtFixedRate 是基于固定时间间隔进行任务调度,ScheduleWithFixedDelay 取决于每次任务执行的时间长短,是基于不固定时间间隔进行任务调度。
代码示例:
public class TestTimeOrder {
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " : 延迟1秒,间隔3秒");
}
};
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
service.scheduleAtFixedRate(runnable, 1000L, 3000L, TimeUnit.MILLISECONDS);
// service.schedule(runnable,100L,TimeUnit.MILLISECONDS);
}
}
以上是用Java方法实现的任务定时运行功能,主要涉及到了线程运行的知识,而且定时时间都是固定比较呆板的。仅供大家参考。如果想要实现复杂的定时功能,比方说,每周一上午10点运行。可以结合Calendar 来实现复杂任务的调度。具体应用方法可参考下文: