Java定时器怎么实现?Timer和线程池方法全攻略
Java实现定时器的方法有很多,这篇文章主要介绍一下博主知道的几种方法。
方法一、使用Timer
1、Timer和TimerTask是java.util包下的类,用于实现定时任务
- 第一步:创建TimerTask定时器任务
- 第二步:创建Timer定时器,调用定时器的方法执行定时器任务
TimerTask是Runnable接口的实现类,Runnable接口的实例通常称为任务。
2、Timer中有两个执行定时任务方法
- schedule()
- scheduleAtFixedRate()
schedule()
void schedule(TimerTask task, Date time)
在时间time执行一次任务(如果指定的事件已经过去了,则马上执行)。
void schedule(TimerTask task, long delay)
在指定时间后执行1次任务(其中delay表示时延,单位是毫秒)。
void schedule(TimerTask task, long delay, long period)
在指定时间后周期性地执行任务(在delay毫秒后,每period毫秒执行一次任务)。
public void schedule(TimerTask task, Date firstTime, long period)
在指定时间后周期性地执行任务(从指定的事件firstTime开始,每period毫秒执行一次任务)。
scheduleAtFixedRate()
void scheduleAtFixedRate(TimerTask task, long delay, long period)
在指定延迟时间后周期性地执行任务(delay毫秒后,每period毫秒执行一次)。
void scheduleAtFixedRate(TimerTask task, Date firstTime,long period)
从指定的日期firstTime开始,每period毫秒执行一次任务。
3、案例代码
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
/**
* @author 沐雨橙风ιε
* @version 1.0
*/
public class TimerExample {
public static void main(String[] args) {
// 创建定时器
Timer timer = new Timer();
// 创建定时器任务
TimerTask task = new TimerTask() {
@Override
public void run() {
System.out.println("Hello world!");
}
};
timer.schedule(task, new Date()); // 马上执行一次
timer.schedule(task, 1000); // 1秒后执行一次
timer.schedule(task, new Date(), 2000); // 每2秒执行一次
timer.schedule(task, 2000, 2000); // 2秒后每2秒执行一次
timer.scheduleAtFixedRate(task, 3000, 3000); // 3秒后每3秒执行一次
timer.scheduleAtFixedRate(task, new Date(), 4000); // 每3秒执行一次
}
}方法二、使用线程池
Java线程池的相关API中有一个类叫做ScheduledExecutorService,专门用于执行定时任务。
其中有几个方法用于执行定时任务:
- schedule()
- scheduleAtFixedRate()
- scheduleWithFixedDelay()
TimeUnit是一个枚举类,用于指定时间单位:
- NANOSECONDS:纳秒
- MICROSECONDS:微秒
- MILISECONDS:毫秒
- SECONDS:秒
- MINUTE:分钟
- HOURS:小时
- DAYS:天
ScheduledExecutorService的方法跟Timer有点细微的区别:有返回值。
- 所有方法的返回值类型都是java.util.concurrent.ScheduledFuture。
schedule()
public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit)
在指定时间后执行1次任务,其中delay表示时延,单位是TimeUnit指定的时间单位。
public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit)
在指定delay个时间单位后执行1次任务,其中delay表示时延。
scheduleAtFixedRate()
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)
在指定延迟时间后周期性地执行任务(在initialDelay个时间单位后,每period个时间单位执行一次)。
scheduleWithFixedDelay()
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)
在指定延迟时间后周期性地执行任务(在initialDelay个时间单位后,每period个时间单位执行一次)。
案例代码
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* @author 沐雨橙风ιε
* @version 1.0
*/
public class ScheduledExecutorServiceExample {
public static void main(String[] args) {
Runnable task = new Runnable() {
@Override
public void run() {
System.out.println("Hello world!");
}
};
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(2);
scheduledThreadPool.schedule(task, 3, TimeUnit.SECONDS);// 3秒后执行一次任务
scheduledThreadPool.schedule(new Callable<Object>() {
@Override
public Object call() throws Exception {
return null;
}
}, 3, TimeUnit.SECONDS); // 3秒后执行一次任务
scheduledThreadPool.scheduleAtFixedRate(task, 3, 3, TimeUnit.SECONDS); // 3秒后,每3秒执行一次任务
scheduledThreadPool.scheduleWithFixedDelay(task, 3, 3, TimeUnit.SECONDS); // 3秒后,每3秒执行一次任务
}
}方法三、使用Spring Task
第一步:在springBoot启动类上添加@EnableScheduling注解
package cn.edu.sgu.www;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* @author 沐雨橙风ιε
* @version 1.0
*/
@EnableScheduling
@SpringBootApplication
public class TimerApplication {
public static void main(String[] args) {
SpringApplication.run(TimerApplication.class, args);
}
}第二步:创建一个定时任务组件
在类的方法上使用@Schedule注解,通过注解的cron属性设置定时器的属性。
package cn.edu.sgu.www.timer;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* @author 沐雨橙风ιε
* @version 1.0
*/
@Component
public class TimerTask {
/**
* cron属性指定在每年的7月18日12:55:00执行一次定时任务
* 对cron表达式感兴趣的可以去学习了解一下
*/
@Scheduled(cron = "0 55 12 18 7 *")
public void task() {
System.out.println("执行定时任务...");
}
}时间到了之后,控制台输出了一次。

方法四、使用Quartz任务调度框架
第一步:在pom.xml中添加quartz的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>第二步:创建定时任务
package cn.edu.sgu.www.timer;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.springframework.stereotype.Component;
/**
* @author 沐雨橙风ιε
* @version 1.0
*/
@Component
public class QuartzJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) {
System.out.println("执行QuartzJob定时任务...");
}
}第三步:配置定时任务触发条件
package cn.edu.sgu.www.config;
import cn.edu.sgu.www.timer.QuartzJob;
import org.quartz.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author 沐雨橙风ιε
* @version 1.0
*/
@Configuration
public class QuartzConfig {
@Bean
public JobDetail jobDetail() {
return JobBuilder.newJob(QuartzJob.class) // 绑定要执行的任务类
.withIdentity("quartzJob") // 设置任务名称
.storeDurably() // 信息持久化
.build();
}
@Bean
public Trigger trigger(JobDetail jobDetail) {
// 定义Cron表达式,每10秒触发一次
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/10 * * * * ?");
return TriggerBuilder.newTrigger()
.forJob(jobDetail) // 绑定JobDetail对象
.withIdentity("trigger") // 定义触发器名称
.withSchedule(cronScheduleBuilder) // 绑定Cron表达式
.build();
}
}总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。


最新评论