任务调度线程池
在【任务调度线程池】功能加入之前,可以使用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);}
