面试题答案
一键面试ScheduledExecutorService相较于Timer和TimerTask的优势
- 线程安全性:
Timer
和TimerTask
不是线程安全的。如果多个任务同时使用Timer
,可能会出现竞态条件等问题。而ScheduledExecutorService
基于线程池实现,线程安全,多个任务可以安全地并发执行。
- 任务调度灵活性:
Timer
的调度依赖于系统时间,如果系统时间发生变化(如手动调整时钟),可能会导致调度不准确。ScheduledExecutorService
基于相对时间调度,不受系统时钟变化的影响,调度更可靠。
- 异常处理:
Timer
在执行TimerTask
时,如果TimerTask
抛出未捕获的异常,Timer
会终止所有任务的执行。而ScheduledExecutorService
中,某个任务抛出异常不会影响其他任务的执行,增强了系统的健壮性。
应用场景
- 定时清理缓存:在一些应用中,需要定时清理缓存以释放内存。可以使用
ScheduledExecutorService
定时执行缓存清理任务,确保系统内存使用处于合理范围。 - 定期数据备份:例如数据库数据备份,需要定期将数据库中的数据备份到其他存储介质。
ScheduledExecutorService
可以方便地实现按照固定时间间隔执行备份任务,保证数据的安全性。
使用ScheduledExecutorService实现按固定延迟时间执行任务的调度器关键代码
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class FixedDelayScheduler {
public static void main(String[] args) {
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleWithFixedDelay(() -> {
System.out.println("执行任务:" + System.currentTimeMillis());
}, 0, 5, TimeUnit.SECONDS);
}
}
在上述代码中:
Executors.newScheduledThreadPool(1)
创建了一个单线程的ScheduledExecutorService
线程池。scheduler.scheduleWithFixedDelay
方法用于按固定延迟时间执行任务。第一个参数是要执行的任务(这里是一个Lambda表达式),第二个参数0
表示首次执行任务的延迟时间为0秒,第三个参数5
表示每次任务执行完毕后,延迟5秒再执行下一次任务,TimeUnit.SECONDS
表示时间单位为秒。