扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
JDK 自带的定时器实现
创新互联是专业的肃南裕固族自治网站建设公司,肃南裕固族自治接单;提供做网站、成都做网站,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行肃南裕固族自治网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!
// schedule(TimerTask task, long delay) 延迟 delay 毫秒 执行
// schedule(TimerTask task, Date time) 特定时间执行
public static void main(String[] args) {
for (int i = 0; i 10; ++i) {
new Timer("timer - " + i).schedule(new TimerTask() {
@Override
public void run() {
println(Thread.currentThread().getName() + " run ");
}
}, 1000);
}
}
2. Quartz 定时器实现
//首先我们需要定义一个任务类,比如为MyJob02 ,
//该类需要继承Job类,然后添加execute(JobExecutionContext context)方法,在
//这个方法中就是我们具体的任务执行的地方。
//由希望由调度程序执行的组件实现的接口
public class MyJob02 implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
// TODO Auto-generated method stub
// 执行响应的任务.
System.out.println("HelloJob.execute,"+new Date());
}
}
public class QuartzTest5 {
public static void main(String[] args) throws Exception {
//SchedulerFactory 是一个接口,用于Scheduler的创建和管理
SchedulerFactory factory = new StdSchedulerFactory();
//从工厂里面拿到一个scheduler实例
//计划表(可能翻译的不太贴切),现在我们有了要做的内容,
//与调度程序交互的主要API
/*
* Scheduler的生命期,从SchedulerFactory创建它时开始,
到Scheduler调用shutdown()方法时结束;Scheduler被创建后,
可以增加、删除和列举Job和Trigger,以及执行其它与调度相关的操作
(如暂停Trigger)。但是,Scheduler只有在调用start()方法后,
才会真正地触发trigger(即执行job)
*/
Scheduler scheduler = factory.getScheduler();
//具体任务.
//用于定义作业的实例
//JobBuilder - 用于定义/构建JobDetail实例,用于定义作业的实例。
JobDetail job = JobBuilder.newJob(MyJob.class).withIdentity("job1", "group1").build();
//Trigger(即触发器) - 定义执行给定作业的计划的组件
//TriggerBuilder - 用于定义/构建触发器实例
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1")
.withSchedule(CronScheduleBuilder.cronSchedule("0/1 * * * * ?")).build();
scheduler.scheduleJob(job, trigger);
scheduler.start();
}
3. Spring boot 任务调度(这个非常容易实现)
/*
* 开启对定时任务的支持
* 在相应的方法上添加@Scheduled声明需要执行的定时任务。
*/
@EnableScheduling
//@EnableScheduling注解来开启对计划任务的支持
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@Component
public class ScheduledTasks {
private Logger logger = LoggerFactory.getLogger(ScheduledTasks.class);
private int i=0;
//0 0 0 2 * ?
@Scheduled(cron="* * * 2 * ?")
//@Scheduled 注解用于标注这个方法是一个定时任务的方法
public void testFixDelay() {
logger.info("执行方法"+i++);
}
java定时任务有三种:
- JDK自带 :JDK自带的Timer以及JDK1.5+ 新增的ScheduledExecutorService;
- Quartz :简单却强大的JAVA作业调度框架
- Spring3.0以后自带的task :可以将它看成一个轻量级的Quartz,而且使用起来比Quartz简单许多;
代码参考:
JDK 自带的定时器实现
schedule(TimerTask task, Date time) 特定时间执行
public static void main(String[] args) {
for (int i = 0; i 10; ++i) {
new Timer("timer - " + i).schedule(new TimerTask() {
@Override
public void run() {
println(Thread.currentThread().getName() + " run ");
}
}, new Date(System.currentTimeMillis() + 2000));
}
}
Quartz 定时器实现
2.1 通过maven引入依赖(这里主要介绍2.3.0) 注意:shiro-scheduler中依赖的是1.x版本 如果同时使用会冲突
!-- --
dependency
groupIdorg.quartz-scheduler/groupId
artifactIdquartz/artifactId
version2.3.0/version
/dependency
2.2 创建Job类
public class TestJob implements Job{
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
println(Thread.currentThread().getName() + " test job begin " + DateUtil.getCurrentTimeStr());
}
}
2.3 调度任务
public static void main(String[] args) throws InterruptedException, SchedulerException {
Scheduler scheduler = new StdSchedulerFactory().getScheduler();
// 开始
scheduler.start();
// job 唯一标识 test.test-1
JobKey jobKey = new JobKey("test" , "test-1");
JobDetail jobDetail = JobBuilder.newJob(TestJob.class).withIdentity(jobKey).build();
Trigger trigger = TriggerBuilder.newTrigger() .withIdentity("test" , "test")
// 延迟一秒执行
.startAt(new Date(System.currentTimeMillis() + 1000))
// 每隔一秒执行 并一直重复
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1).repeatForever())
.build();
scheduler.scheduleJob(jobDetail , trigger);
Thread.sleep(5000);
// 删除job
scheduler.deleteJob(jobKey);
}
3.Spring 相关的任务调度
3.1 配置文件实现
spring-schedule.xml
task:scheduler id="myScheduler" pool-size="10" /
task:scheduled-tasks scheduler="myScheduler"
task:scheduled ref="job" method="test" cron="0 * * * * ?"/
/task:scheduled-tasks
3.2注解实现
spring-schedule.xml
task:scheduler id="myScheduler" pool-size="10" /
// 启用注解
task:annotation-driven scheduler="myScheduler"/
@Component
public class Task{
@Scheduled(cron="0/5 * * * * ? ") //每5秒执行一次
public void execute(){
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(sdf.format(DateTime.now().toDate())+"*********B任务每5秒执行一次进入测试");
}
}
在应用里经常都有用到在后台跑定时任务的需求。举个例子,比如需要在服务后台跑一个定时任务来进行非实时计算,清除临时数据、文件等。在本文里,3种不同的实现方法:
普通thread实现
TimerTask实现
ScheduledExecutorService实现
1.普通thread
这是最常见的,创建一个thread,然后让它在while循环里一直运行着,通过sleep方法来达到定时任务的效果。这样可以快速简单的实现,代码如下:
public class Task1 {
public static void main(String[] args) {
// run in a second
final long timeInterval = 1000;
Runnable runnable = new Runnable() {
public void run() {
while (true) {
// ------- code for task to run
System.out.println("Hello !!");
// ------- ends here
try {
Thread.sleep(timeInterval);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Thread thread = new Thread(runnable);
thread.start();
}
}
2.用Timer和TimerTask
上面的实现是非常快速简便的,但它也缺少一些功能。
用Timer和TimerTask的话与上述方法相比有如下好处:
当启动和去取消任务时可以控制
第一次执行任务时可以指定你想要的delay时间
在实现时,Timer类可以调度任务,TimerTask则是通过在run()方法里实现具体任务。
Timer实例可以调度多任务。
当Timer的构造器被调用时,创建了一个线程,这个线程可以用来调度任务:
import java.util.Timer;
import java.util.TimerTask;
public class Task2 {
public static void main(String[] args) {
TimerTask task = new TimerTask() {
@Override
public void run() {
// task to run goes here
System.out.println("Hello !!!");
}
};
Timer timer = new Timer();
long delay = 0;
long intevalPeriod = 1 * 1000;
// schedules the task to be run in an interval
timer.scheduleAtFixedRate(task, delay,
intevalPeriod);
} // end of main
}
3.ScheduledExecutorService
ScheduledExecutorService是从Java SE 5的java.util.concurrent里,做为并发工具类被引进的,这是最理想的定时任务实现方式。
相比于上两个方法,它有以下好处:
相比于Timer的单线程,它是通过线程池的方式来执行任务的
可以很灵活的去设定第一次执行任务delay时间
提供了良好的约定,以便设定执行的时间间隔
通过ScheduledExecutorService#scheduleAtFixedRate展示这个例子,通过代码里参数的控制,首次执行加了delay时间:
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Task3 {
public static void main(String[] args) {
Runnable runnable = new Runnable() {
public void run() {
// task to run goes here
System.out.println("Hello !!");
}
};
ScheduledExecutorService service = Executors
.newSingleThreadScheduledExecutor();
service.scheduleAtFixedRate(runnable, 0, 1, TimeUnit.SECONDS);
}
}
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流