定时器
- 1.定时器的多种实现
- 1.1 Timer + TimerTask)
- 1.2 ScheduledExecutorService
1.定时器的多种实现
- JDK自带的Timer + TimerTask
- 优点:
- 简单易用, 支持延迟执行和周期性执行任务
- 缺点:
- 在多线程环境下存在问题, 例如任务执行时间较长, 可能会影响其他任务的执行
- 不适合在需要精确控制任务执行时间的场景
- 优点:
- JDK提供的ScheduledExecutorService接口
- 优点
- 支持延迟执行和周期性执行任务
- 用线程池来管理任务执行, 更灵活, 性能更好
- 提供更多的任务调度策略
- 缺点
- 相较于Timer类,稍微复杂一些,需要手动创建线程池和调度器。
- 优点
- Spring的@Scheduled注解
- Quartz框架
1.1 Timer + TimerTask)
java.util包下的类, 用于实现定时任务
实现步骤:
步骤一: 创建定时任务
, 可以通过匿名内部类来实现. 在run()中执行任务
步骤二: 创建定时器, 调用定时器的方法执行定时任务
public static void main(String[] args) {// 创建定时器Timer timer = new Timer();// 创建定时器任务TimerTask task = new TimerTask() {@Overridepublic void run() {System.out.println("Hello world!");}};timer.schedule(task, 1000); // 1秒后执行一次timer.schedule(task, 2000, 2000); // 两秒后每两秒执行一次timer.scheduleAtFixedRate(task, 3000, 3000); // 3秒后每3秒执行一次timer.scheduleAtFixedRate(task, new Date(), 4000); // 每4秒执行一次
}
1.2 ScheduledExecutorService
public static void main(String[] args) {// 创建定时器任务TimerTask timerTask = new TimerTask() {@Overridepublic void run() {System.out.println("Hello world!");}};ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(2);scheduledThreadPool.schedule(timerTask, 1000, TimeUnit.MILLISECONDS);scheduledThreadPool.scheduleAtFixedRate(timerTask, 1000, 1000, TimeUnit.MILLISECONDS);
}
如果我们想在SpringBoot中使用ScheduledExecutorService
- 在配置类中配置Bean(ScheduledExecutorService)
@Configuration
public class ScheduledExecutorConfig {@Bean(destroyMethod = "shutdown")public ScheduledExecutorService scheduledExecutorService() {return Executors.newScheduledThreadPool(5); // 创建一个大小为5的线程池}
}
- 创建任务类
- 在Bean初始化时(@PostConstruct), 启动定时任务, 每5秒执行
- 将ScheduledFuture对象保存起来, 在需要取消定时任务的时候调用cancel()
@Component
public class MyScheduledTask {private ScheduledFuture<?> scheduledFuture;@Autowiredprivate ScheduledExecutorService scheduledExecutorService;@PostConstructpublic void scheduleTask() {Runnable task = () -> {// 定时任务逻辑System.out.println("Task executed!");};// 每隔5秒执行一次任务scheduledFuture = scheduledExecutorService.scheduleAtFixedRate(task, 0, 5, TimeUnit.SECONDS);}public Boolean cancel() {if (scheduledFuture != null) {return scheduledFuture.cancel(false);}return false;}}