java定时_Java定时任务

Java开发过程中经常会遇到使用定时任务的情况,我总结了一下有如下四种方式:Timer、ScheduledExecutorService、SpringTask、Quartz。

一、使用java的Timer

1、Timer

new Timer("testTimer").schedule(new TimerTask() {

@Override

public void run() {

System.out.println("TimerTask");

}

}, 1000,2000);

解释:1000ms是延迟启动时间,2000ms是定时任务周期,每2s执行一次

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

try {

Date date = dateFormat.parse("2018-07-11 12:00:00.000");

new Timer("testTimer1").scheduleAtFixedRate(new TimerTask() {

@Override

public void run() {

System.out.println("TimerTask");

}

}, date,2000);

} catch (ParseException e) {

e.printStackTrace();

}

解释:date是开始时间,2000ms是定时任务周期,每2s执行一次

timer有2中方法schedule和scheduleAtFixedRate,前者会等任务结束在开始计算时间间隔,后者是在任务开始就计算时间,有并发的情况

二、使用ScheduledExecutorService

1、ScheduledExecutorService

scheduledExecutorService.schedule(new Runnable() {

@Override

public void run() {

System.out.println("ScheduledTask");

}

},1, TimeUnit.SECONDS);

解释:延迟1s启动,执行一次

ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(10);

scheduledExecutorService.scheduleAtFixedRate(new Runnable() {

@Override

public void run() {

System.out.println("ScheduledTask");

}

}, 1, 1, TimeUnit.SECONDS);

解释:延迟1s启动,每隔1s执行一次,是前一个任务开始时就开始计算时间间隔,但是会等上一个任务结束在开始下一个

ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(10);

scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {

@Override

public void run() {

System.out.println("ScheduledTask");

}

}, 1, 1, TimeUnit.SECONDS);

解释:延迟1s启动,在前一个任务执行完成之后,延迟1s在执行

三、使用SpringTask

1、写任务类

package com.zb.timedtask;

import com.zb.controller.StudentController;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.scheduling.annotation.Scheduled;

import org.springframework.stereotype.Service;

@Service

public class SpringTask {

private static final Logger log = LoggerFactory.getLogger(SpringTask.class);

@Scheduled(cron = "1/5 * * * * *")

public void task1(){

log.info("springtask 定时任务!");

}

@Scheduled(initialDelay = 1000,fixedRate = 1*1000)

public void task2(){

log.info("springtask 定时任务!");

}

}

解释:

task1是每隔5s执行一次,{秒} {分} {时} {日期} {月} {星期}

task2是延迟1s,每隔1S执行一次

2、配置文件修改

(1)简单版

(2)任务池版

(3)解释

假如只有一个定时任务,可以用简单版;如果有多个定时任务,则要用任务池,不然它会顺序执行。

两个任务的时间间隔为:执行时间+设定的定时间隔

例子:(这个任务8s执行一次)

@Scheduled(cron = "1/4 * * * * *")

public void task2(){

log.info("springtask 定时任务2!");

try {

TimeUnit.SECONDS.sleep(4);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

四、使用Quartz框架

1、加依赖

org.quartz-scheduler

quartz

2.3.0

org.springframework

spring-context-support

4.3.4.RELEASE

2、Job实现

package com.zb.quartz;

import org.quartz.Job;

import org.quartz.JobExecutionContext;

import org.quartz.JobExecutionException;

import java.text.SimpleDateFormat;

import java.util.Date;

public class HelloWorldJob implements Job {

@Override

public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {

String strTime = new SimpleDateFormat("HH-mm-ss").format(new Date());

System.out.println( strTime + ":Hello World!");

}

}

3、调度器(可以用listener在项目启动时执行)

import org.quartz.*;

import org.quartz.impl.StdSchedulerFactory;

public class MyScheduler {

public static void main(String[] args) throws SchedulerException {

//创建调度器Schedule

SchedulerFactory schedulerFactory = new StdSchedulerFactory();

Scheduler scheduler = schedulerFactory.getScheduler();

//创建JobDetail实例,并与HelloWordlJob类绑定

JobDetail jobDetail = JobBuilder.newJob(HelloWorldJob.class).withIdentity("job1", "jobGroup1")

.build();

//创建触发器Trigger实例(立即执行,每隔1S执行一次)

Trigger trigger = TriggerBuilder.newTrigger()

.withIdentity("trigger1", "triggerGroup1")

.startNow()

.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1).repeatForever())

.build();

//开始执行

scheduler.scheduleJob(jobDetail, trigger);

scheduler.start();

}

}

解释:上面用的是简单触发器,也可以用Con触发器,如下

Trigger cronTrigger = TriggerBuilder.newTrigger()

.withIdentity("trigger2", "triggerGroup2")

.startNow()

.withSchedule(cronSchedule("0 42 10 * * ?"))

.build();

4、整合spring

也可以直接把上面的调度器写成配置文件,整合spring

(1)job

package com.zb.quartz;

import java.text.SimpleDateFormat;

import java.util.Date;

public class QuarFirstJob {

public void first() {

String strTime = new SimpleDateFormat("HH-mm-ss").format(new Date());

System.out.println( strTime + ":Hello World!");

}

}

(2)配置文件

class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">

first

class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">

0/5 * * * * ?

class="org.springframework.scheduling.quartz.SchedulerFactoryBean">

5、时间

public class QuarFirstJob {

public void first() {

try {

TimeUnit.SECONDS.sleep(6);

} catch (InterruptedException e) {

e.printStackTrace();

}

String strTime = new SimpleDateFormat("HH-mm-ss").format(new Date());

System.out.println( strTime + ":Hello World!");

}

}

上面的配置里面写是5s间隔,把上面的sleep时间分别改成4和6,发现两次任务间隔是执行时间和间隔时间的最大值,分别是5,6

总结

Quartz是执行时间和间隔时间的最大值(比如;执行时间是3s,间隔是2s,则每3s执行一次;执行时间是3s,间隔是5s,则每5s执行一次。)

Spring task是执行时间+间隔时间(比如;执行时间是3s,间隔是2s,则每5s执行一次;执行时间是3s,间隔是5s,则每8s执行一次。)

timer有2中方法schedule和scheduleAtFixedRate,前者会等任务结束在开始计算时间间隔,后者是在任务开始就计算时间,有并发的情况

ScheduledExecutorService的scheduleAtFixedRate类似Quartz,scheduleWithFixedDelay类似SpringTask

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值