任务调度线程池
在【任务调度线程池】功能加入之前,可以使用java.util.Timer来实现定时功能,Timer的优点在于简单易用,但是所有任务都是由一个线程来调度,因此所有任务都是串行执行的,同一时间只能有一个任务在执行,前一个任务的延时或异常都将会影响到之后的任务
ScheduledExecutorService—-带有任务调度功能的线程池
定时任务:
public static void main(String[] args) throws ExecutionException, InterruptedException {
ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);
log.debug("start...");
pool.scheduleAtFixedRate(() -> {
log.debug("running....");
//如果执行的时间超过延时时间,则以任务为准,间隔时间执行时间被消耗
sleep(2);
}, 1, 1, TimeUnit.SECONDS);
}
在执行任务消耗时间的基础上进行延时的定时任务
public static void main(String[] args) throws ExecutionException, InterruptedException {
ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);
pool.scheduleWithFixedDelay(() -> {
log.debug("running---");
sleep(2);
}, 1, 1, TimeUnit.SECONDS);
}
延时任务:
public static void main(String[] args) throws ExecutionException,InterruptedException {
ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);
pool.schedule(() -> {
log.debug("task1");
//有异常或者执行慢都不会影响下面任务的执行,前提是连接数量足够
int i = 1 / 0;
}, 1, TimeUnit.SECONDS);
pool.schedule(() -> {
log.debug("task2");
}, 1, TimeUnit.SECONDS);
}
应用:
//定时任务:每周四18:00:00定时执行
public static void main(String[] args) {
//获取当前时间
LocalDateTime now = LocalDateTime.now();
//获取周四时间
LocalDateTime time = now.withHour(18).withMinute(0).withSecond(0).withNano(0).with(DayOfWeek.THURSDAY);
//如果当前时间>本周周四,则要找到下周四
if (now.compareTo(time) > 0) {
time = time.plusWeeks(1);
}
//1周的时间
long period = 1000 * 60 * 60 * 24 * 7;
//当前时间和周四的时间差
long initialDealy = Duration.between(now, time).toMillis();
ScheduledExecutorService pool = Executors.newScheduledThreadPool(1);
pool.scheduleAtFixedRate(() -> {
System.out.println("running---");
}, initialDealy, period, TimeUnit.SECONDS);
}