ScheduledExecutorService和ScheduledThreadPoolExecutor
定时任务的四种形式:
1.无返回值,入参Runnable
private static void testScheduledFutureRunnable() { ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2); //Runnable ScheduledFuture<?> future1 = executor.schedule(() -> System.out.println("I will be invoked."), 2, TimeUnit.SECONDS); //如果被取消,Runnable里面的业务将不会被执行 System.out.println(future1.cancel(true)); }
2.有返回值,入参Callable
private static void testScheduledFutureCallable() throws InterruptedException, ExecutionException { ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2); //Callable ScheduledFuture<Integer> future2 = executor.schedule(() -> 3, 2, TimeUnit.SECONDS); System.out.println(future2.get()); }
3.以实际的任务执行时间为周期类似于Timer
private static void testScheduleAtFixedRate() { /** * period 2 seconds execute a task. * but the task spend 5 seconds actually * * solution 1:(crontab/quartz/Control-M) * period first policy 周期优先策略 * * 这三种执行结果: * 0 : 5 * 2 : 5 * 4 : 5 * * solution 2 :(JDK Timer) 任务优先策略 * 0 : 5 * 5 : 5 * 10: 5 */ ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2); //任务优先--以实际的任务执行时间为周期 final AtomicLong interval = new AtomicLong(0L); ScheduledFuture<?> future3 = executor.scheduleAtFixedRate(() -> { long currentTimeMillis = System.currentTimeMillis(); if(interval.get() == 0) { System.out.printf("The first time trigger task at %d\n", currentTimeMillis); } else { System.out.printf("The actually spend [%d]\n", currentTimeMillis - interval.get()); } interval.set(currentTimeMillis); System.out.println(Thread.currentThread().getName()); try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } }, 1, 2, TimeUnit.SECONDS); }
4.以实际的任务执行时间+延长时间和为周期
private static void testScheduleWithFixedDelay() { ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2); final AtomicLong interval = new AtomicLong(0L); //以实际的任务执行时间+延长时间和为周期 ScheduledFuture<?> future4 = executor.scheduleWithFixedDelay(() -> { long currentTimeMillis = System.currentTimeMillis(); if(interval.get() == 0) { System.out.printf("The first time trigger task at %d\n", currentTimeMillis); } else { System.out.printf("The actually spend [%d]\n", currentTimeMillis - interval.get()); } interval.set(currentTimeMillis); System.out.println(Thread.currentThread().getName()); try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } }, 1, 2, TimeUnit.SECONDS); }
两种方法:
1.scheduleAtFixedRate和getContinueExistingPeriodicTasksAfterShutdownPolicy配合使用
private static void test1() throws InterruptedException { ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2); //打断之后允许周期性任务继续执行,默认false System.out.println(executor.getContinueExistingPeriodicTasksAfterShutdownPolicy()); //true 允许周期性任务继续执行 executor.setContinueExistingPeriodicTasksAfterShutdownPolicy(true); //任务优先--以实际的任务执行时间为周期 final AtomicLong interval = new AtomicLong(0L); ScheduledFuture<?> future3 = executor.scheduleAtFixedRate(() -> { long currentTimeMillis = System.currentTimeMillis(); if(interval.get() == 0) { System.out.printf("The first time trigger task at %d\n", currentTimeMillis); } else { System.out.printf("The actually spend [%d]\n", currentTimeMillis - interval.get()); } interval.set(currentTimeMillis); System.out.println(Thread.currentThread().getName()); try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } }, 1, 2, TimeUnit.SECONDS); TimeUnit.MILLISECONDS.sleep(1200); executor.shutdown(); }
2.scheduleWithFixedDelay和getExecuteExistingDelayedTasksAfterShutdownPolicy配合使用
private static void test2() throws InterruptedException { ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2); //被打断之后继续按照固定任务时间+延迟时间为周期执行,默认是true,被打断后继续执行当前任务 System.out.println(executor.getExecuteExistingDelayedTasksAfterShutdownPolicy()); // executor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false); final AtomicLong interval = new AtomicLong(0L); //以实际的任务执行时间+指定周期时间和为周期 ScheduledFuture<?> future4 = executor.scheduleWithFixedDelay(() -> { long currentTimeMillis = System.currentTimeMillis(); if(interval.get() == 0) { System.out.printf("The first time trigger task at %d\n", currentTimeMillis); } else { System.out.printf("The actually spend [%d]\n", currentTimeMillis - interval.get()); } interval.set(currentTimeMillis); System.out.println(Thread.currentThread().getName()); try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } }, 1, 2, TimeUnit.SECONDS); TimeUnit.MILLISECONDS.sleep(1200); executor.shutdown(); }