定时任务-ScheduledExecutorService
创建定时任务线程池的方式
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(4);// 不推荐
// 或
ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(4);// 推荐
创建定时任务的方法
public interface ScheduledExecutorService extends ExecutorService { /** * 延迟delay(时间单位由unit指定)后执行任务 * * @param command 任务 * @param delay 延迟时间 * @param unit 时间单位 * @return 执行结果 */ public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit); /** * 延迟delay(时间单位由unit指定)时间后执行任务 * 任务执行完毕后,返回执行结果 * * @param callable 任务 * @param delay 延迟时间 * @param unit 时间单位 * @return 执行结果 */ public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit); /** * 延迟delay时间后执行第一次任务,之后每过period毫秒执行一次。 * 假设: * 执行一次任务需要消耗的时间为 exeTime * 执行此次任务的开始时间是 nowTime * 执行下一次任务的实际时间是 actuallyTime * 如果 exeTime >= period ,那么,actuallyTime >= nowTime + exeTime; * 如果 exeTime < period , 那么,actuallyTime >= nowTime + period; * * @param command 任务 * @param initialDelay 执行首次任务之前的延时时间 * @param period 周期性执行任务,相邻两次的时间间隔 * @param unit 时间单位 * @return 执行结果 */ public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit); /** * 延迟initialDelay时间后执行首次任务,之后的任务执行,全部在上次任务执行完毕之后,再延迟delay时间执行。 * * 假设: * 执行一次任务需要消耗的时间为 exeTime * 执行此次任务的开始时间是 nowTime * 执行下一次任务的实际时间是 actuallyTime * 如果 exeTime >= period ,那么,actuallyTime >= nowTime + exeTime + delay; * 如果 exeTime < period , 那么,actuallyTime >= nowTime + exeTime + period; * * @param command 任务 * @param initialDelay 执行首次任务之前的延迟时间 * @param delay 每次任务执行完成后,执行下次任务之前的延迟时间 * @param unit 时间单位 * @return */ public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit); }
创建定时任务的示例
示例一:延迟执行
package com.java.scheduled.task.pool; import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class ScheduledTaskDemo01 { public static void main(String[] args) { ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(4); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date = new Date(); System.out.println("安排执行任务的时间:"+sdf.format(date)); long c1 = date.getTime(); Runnable runnable = () -> { Date nowDate = new Date(); System.out.println("****计划任务(1):【延迟2秒执行】"); System.out.println("实际执行任务的时间:"+sdf.format(nowDate)); System.out.println("延迟时间:"+(nowDate.getTime() - c1)+"ms"); }; executorService.schedule(runnable, 2, TimeUnit.SECONDS); } }
执行结果如下:
安排执行任务的时间:2019-05-28 12:10:46 ****计划任务(1):【延迟2秒执行】 实际执行任务的时间:2019-05-28 12:10:48 延迟时间:2087ms
示例二:延迟执行,返回结果
package com.java.scheduled.task.pool; import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurrent.*; public class ScheduledTaskDemo02 { public static void main(String[] args) { ScheduledExecutorService executorService = Executors.newScheduledThreadPool(4); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date = new Date(); System.out.println("安排执行任务的时间:"+sdf.format(date)); long c2 = date.getTime(); Callable<String> callable = () -> { Date nowDate = new Date(); System.out.println("****计划任务(2):【延迟2秒执行,执行结束返回结果】"); System.out.println("实际执行任务的时间:"+sdf.format(nowDate)); System.out.println("延迟时间:"+(nowDate.getTime() - c2)+"ms"); Thread.sleep(1000); System.out.println("任务执行完毕,当前时间:"+sdf.format(new Date())); return "success"; }; ScheduledFuture<String> scheduledFuture = executorService.schedule(callable, 2, TimeUnit.SECONDS); try { System.out.println("任务的执行结果:"+scheduledFuture.get()); } catch (ExecutionException e1) { e1.printStackTrace(); } catch (InterruptedException e2) { e2.printStackTrace(); } } }
执行结果如下:
安排执行任务的时间:2019-05-28 12:14:05 ****计划任务(2):【延迟2秒执行,执行结束返回结果】 实际执行任务的时间:2019-05-28 12:14:07 延迟时间:2072ms 任务执行完毕,当前时间:2019-05-28 12:14:08 任务的执行结果:success
示例三:延迟+周期性执行任务
package com.java.scheduled.task.pool; import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class ScheduledTaskDemo03 { public static void main(String[] args) { ScheduledExecutorService executorService = Executors.newScheduledThreadPool(4); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date = new Date(); System.out.println("安排执行任务的时间:"+sdf.format(date)); long c3 = date.getTime(); Runnable runnable = new Runnable() { long exeTime = c3; @Override public void run() { Date nowDate = new Date(); System.out.println("--------------------------------------------------------------------------------"); System.out.println("计划任务(3):【延迟1秒执行第一次任务,之后每过2秒执行一次任务】"); System.out.println("****实际执行任务的时间:"+sdf.format(nowDate)); System.out.println("****距离上次执行任务的时间间隔:"+(nowDate.getTime() - exeTime)+"ms"); try { Thread.sleep(4000); } catch (InterruptedException e) {} exeTime = nowDate.getTime(); } }; executorService.scheduleAtFixedRate(runnable, 1, 2, TimeUnit.SECONDS); } }
执行结果如下:
安排执行任务的时间:2019-05-28 12:15:12 -------------------------------------------------------------------------------- 计划任务(3):【延迟1秒执行第一次任务,之后每过2秒执行一次任务】 ****实际执行任务的时间:2019-05-28 12:15:13 ****距离上次执行任务的时间间隔:1003ms -------------------------------------------------------------------------------- 计划任务(3):【延迟1秒执行第一次任务,之后每过2秒执行一次任务】 ****实际执行任务的时间:2019-05-28 12:15:17 ****距离上次执行任务的时间间隔:4002ms -------------------------------------------------------------------------------- 计划任务(3):【延迟1秒执行第一次任务,之后每过2秒执行一次任务】 ****实际执行任务的时间:2019-05-28 12:15:21 ****距离上次执行任务的时间间隔:4001ms -------------------------------------------------------------------------------- 计划任务(3):【延迟1秒执行第一次任务,之后每过2秒执行一次任务】 ****实际执行任务的时间:2019-05-28 12:15:25 ****距离上次执行任务的时间间隔:4002ms
示例四:初始延迟+周期性延迟执行任务
package com.java.scheduled.task.pool; import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class ScheduledTaskDemo04 { public static void main(String[] args) { ScheduledExecutorService executorService = Executors.newScheduledThreadPool(4); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date = new Date(); System.out.println("安排执行任务的时间:"+sdf.format(date)); long c3 = date.getTime(); Runnable runnable = new Runnable() { long exeTime = c3; @Override public void run() { Date nowDate = new Date(); System.out.println("--------------------------------------------------------------------------------"); System.out.println("计划任务(4):【延迟1秒执行第一次任务,之后每过2秒执行一次任务】"); System.out.println("****实际执行任务的时间:"+sdf.format(nowDate)); System.out.println("****距离上次执行任务的时间间隔:"+(nowDate.getTime() - exeTime)+"ms"); try { Thread.sleep(2500); } catch (InterruptedException e) {} exeTime = nowDate.getTime(); } }; executorService.scheduleWithFixedDelay(runnable, 1, 2, TimeUnit.SECONDS); } }
执行结果如下:
安排执行任务的时间:2019-05-28 12:16:56 -------------------------------------------------------------------------------- 计划任务(4):【延迟1秒执行第一次任务,之后每过2秒执行一次任务】 ****实际执行任务的时间:2019-05-28 12:16:57 ****距离上次执行任务的时间间隔:1018ms -------------------------------------------------------------------------------- 计划任务(4):【延迟1秒执行第一次任务,之后每过2秒执行一次任务】 ****实际执行任务的时间:2019-05-28 12:17:01 ****距离上次执行任务的时间间隔:4504ms -------------------------------------------------------------------------------- 计划任务(4):【延迟1秒执行第一次任务,之后每过2秒执行一次任务】 ****实际执行任务的时间:2019-05-28 12:17:06 ****距离上次执行任务的时间间隔:4502ms -------------------------------------------------------------------------------- 计划任务(4):【延迟1秒执行第一次任务,之后每过2秒执行一次任务】 ****实际执行任务的时间:2019-05-28 12:17:10 ****距离上次执行任务的时间间隔:4502ms