Java Executor框架通过ScheduledExecutorService接口及其实现类ScheduledThreadPoolExecutor提供了强大的任务调度能力,支持延迟执行、周期性执行等多种策略,满足不同场景下的定时任务需求。以下是具体的调度策略及实现细节:
延迟执行是指任务在提交后,经过指定的延迟时间再执行一次。这种策略适用于“稍后执行”的场景,如延迟发送通知、定时检查等。
实现方法:通过ScheduledExecutorService.schedule()方法实现,该方法接受三个参数:Runnable/Callable任务、延迟时间、时间单位(如TimeUnit.SECONDS)。
示例代码:
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.schedule(() -> System.out.println("任务延迟3秒后执行"), 3, TimeUnit.SECONDS);
scheduler.shutdown();
关键说明:任务仅执行一次,延迟时间从任务提交时刻开始计算。
固定频率执行是指任务以固定的时间间隔重复执行,无论上一个任务是否完成。这种策略适用于“严格按时间间隔触发”的场景,如数据同步、日志采集等。
实现方法:通过ScheduledExecutorService.scheduleAtFixedRate()方法实现,参数包括:任务、初始延迟、周期时间、时间单位。
执行逻辑:周期时间(period)= 下一次任务开始时间 - 上一次任务开始时间。若任务执行时间超过周期,新任务会在旧任务未完成时启动,可能导致任务重叠。
示例代码:
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
scheduler.scheduleAtFixedRate(() -> {
System.out.println("固定频率任务执行:" + System.currentTimeMillis());
try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); }
}, 0, 1, TimeUnit.SECONDS); // 初始延迟0秒,每1秒执行一次
关键说明:适合执行时间短且稳定的任务,需注意任务重叠问题。
固定延迟执行是指任务以固定的延迟时间重复执行,延迟时间从上一个任务完成时刻开始计算。这种策略适用于“任务完成后等待固定时间再执行”的场景,如文件处理、报表生成等。
实现方法:通过ScheduledExecutorService.scheduleWithFixedDelay()方法实现,参数与固定频率类似,但period表示“任务完成到下一次开始的延迟时间”。
执行逻辑:周期时间 = 下一次任务开始时间 - 上一次任务结束时间。无论任务执行时间长短,两次执行之间始终保持固定延迟。
示例代码:
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleWithFixedDelay(() -> {
System.out.println("固定延迟任务执行:" + System.currentTimeMillis());
try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); }
}, 0, 1, TimeUnit.SECONDS); // 初始延迟0秒,任务完成后延迟1秒再执行
关键说明:适合执行时间长的任务,避免任务重叠。
调度策略的效果与线程池配置密切相关,合理的配置能提升调度效率和系统稳定性:
ArrayBlockingQueue(有界队列),避免LinkedBlockingQueue(无界队列)导致的内存溢出;队列容量建议设置为线程数的3-5倍。CallerRunsPolicy(调用者线程执行):适合允许任务降级的场景(如后台任务)。DiscardOldestPolicy(丢弃最老任务):适合实时性要求高的场景(如最新订单处理)。shutdown()方法平缓关闭线程池(等待已提交任务完成),或shutdownNow()方法粗暴关闭(尝试取消所有任务)。PriorityBlockingQueue实现,需自定义Runnable/Callable任务实现Comparable接口,根据优先级排序。ThreadPoolExecutor priorityExecutor = new ThreadPoolExecutor(
4, 8, 60, TimeUnit.SECONDS,
new PriorityBlockingQueue<>(100),
new ThreadFactoryBuilder().setNameFormat("priority-task-%d").build()
);
priorityExecutor.execute(new PriorityTask(1)); // 高优先级
priorityExecutor.execute(new PriorityTask(3)); // 低优先级
Future.cancel()取消现有任务,再重新调用scheduleAtFixedRate()/scheduleWithFixedDelay()调整调度频率。ScheduledExecutorService的调度策略通过灵活的参数配置和线程池管理,能够满足大多数定时任务需求。在实际应用中,需根据任务特性(执行时间、稳定性)和业务要求(实时性、可靠性)选择合适的策略,并通过合理的线程池配置优化调度效率。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。