任务调度线程池

在【任务调度线程池】功能加入之前,可以使用java.util.Timer来实现定时功能,Timer的优点在于简单易用,但是所有任务都是由一个线程来调度,因此所有任务都是串行执行的,同一时间只能有一个任务在执行,前一个任务的延时或异常都将会影响到之后的任务


ScheduledExecutorService—-带有任务调度功能的线程池

定时任务:

  1. public static void main(String[] args) throws ExecutionException, InterruptedException {
  2. ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);
  3. log.debug("start...");
  4. pool.scheduleAtFixedRate(() -> {
  5. log.debug("running....");
  6. //如果执行的时间超过延时时间,则以任务为准,间隔时间执行时间被消耗
  7. sleep(2);
  8. }, 1, 1, TimeUnit.SECONDS);
  9. }

在执行任务消耗时间的基础上进行延时的定时任务

  1. public static void main(String[] args) throws ExecutionException, InterruptedException {
  2. ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);
  3. pool.scheduleWithFixedDelay(() -> {
  4. log.debug("running---");
  5. sleep(2);
  6. }, 1, 1, TimeUnit.SECONDS);
  7. }

延时任务:

  1. public static void main(String[] args) throws ExecutionException,InterruptedException {
  2. ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);
  3. pool.schedule(() -> {
  4. log.debug("task1");
  5. //有异常或者执行慢都不会影响下面任务的执行,前提是连接数量足够
  6. int i = 1 / 0;
  7. }, 1, TimeUnit.SECONDS);
  8. pool.schedule(() -> {
  9. log.debug("task2");
  10. }, 1, TimeUnit.SECONDS);
  11. }

应用:
  1. //定时任务:每周四18:00:00定时执行
  2. public static void main(String[] args) {
  3. //获取当前时间
  4. LocalDateTime now = LocalDateTime.now();
  5. //获取周四时间
  6. LocalDateTime time = now.withHour(18).withMinute(0).withSecond(0).withNano(0).with(DayOfWeek.THURSDAY);
  7. //如果当前时间>本周周四,则要找到下周四
  8. if (now.compareTo(time) > 0) {
  9. time = time.plusWeeks(1);
  10. }
  11. //1周的时间
  12. long period = 1000 * 60 * 60 * 24 * 7;
  13. //当前时间和周四的时间差
  14. long initialDealy = Duration.between(now, time).toMillis();
  15. ScheduledExecutorService pool = Executors.newScheduledThreadPool(1);
  16. pool.scheduleAtFixedRate(() -> {
  17. System.out.println("running---");
  18. }, initialDealy, period, TimeUnit.SECONDS);
  19. }