自定义定时任务
通过JDK自带了多种实现定时任务的接口:juc中的线程池,定时器Timer,死循环,juc延时队列。我们就使用juc延时队列来实现自定义的定时任务。
适用场景
周报、月度报表之类的统计数据任务。
优点:
异步执行、实现代码的解耦合
数据批量处理
时间驱动
实现代码
创建自定义定时任务类,实现Delay接口
class DelayTask implements Delayed {
private long timeout;//任务执行时间
private DelayQueue<DelayTask> delayQueue = new DelayQueue<>();
/**
* return值小于等于0时该任务执行
*
* @param unit
* @return
*/
@Override
public long getDelay(TimeUnit unit) {
return this.timeout - System.currentTimeMillis();
}
/**
* 排序方法
*
* @param o
* @return
*/
@Override
public int compareTo(Delayed o) {
return (int) (this.timeout - ((DelayTask) o).timeout);
}
/**
* @param task 执行的任务
* @param delay 延迟时间
* @param timeUtil 时间单位
*/
public void scheduled(Runnable task, Long delay, TimeUnit timeUtil) {
this.timeout = System.currentTimeMillis() + timeUtil.toMillis(delay);
try {
delayQueue.put(this);
delayQueue.take();
new Thread(task).start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* @param task 执行任务
* @param delay 延迟时间
* @param period 执行周期
* @param timeUtil 时间单位
*/
public void scheduled(Runnable task, Long delay, Long period, TimeUnit timeUtil) {
this.timeout = System.currentTimeMillis() + timeUtil.toMillis(delay);
try {
while (true) {
delayQueue.put(this);
delayQueue.take();
new Thread(task).start();
this.timeout = System.currentTimeMillis() + timeUtil.toMillis(period);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
写测试类
public class TimerDemo {
public static void main(String[] args) {
System.out.println("这是初始化时的系统时间: " + System.currentTimeMillis());
new DelayTask().scheduled(() -> {
System.out.println("这是自定义的定时任务,执行时间:" + System.currentTimeMillis());
}, 5l, 10l, TimeUnit.SECONDS);
}
}
测试自定义定时任务,测试方法中表明,在系统启动5秒后执行第一次任务,之后每隔10秒执行一次,结果如下: