java quartz timer_Java 定时调度Timer&Quartz

目录

三、Quartz

一、Java定时任务介绍

在Java中,用得比较多的有两种,一个是Timer,一个是Quartz;

其中Timer是这是jdk自带的类库,一般用来实现简单的定时调度,由一个后台线程进行任务的调度,所以对于并发调度不友好;

Quartz不是jdk自带的,但是他的功能更加强大,一般用于比较复杂的定时调度,可以解决Timer的并发调度问题;

二、Timer

2.1、Timer与TimerTask

Timer是在jdk自带的工具类,Timer为与java.util包下,可以将其理解为一个“定时器”;

当定时器到点后,执行的任务是TimerTask,称为“任务”;

下面就是一个TimerTask示例,注意需要重写TimerTask的run方法,类似于Runnable接口的run方法。

package cn.ganlixin.task;

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.TimerTask;

public class MyTask extends TimerTask {

@Override

public void run() {

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

System.out.println(dateFormat.format(new Date()));

}

}

下面是一个简单的定时执行任务的示例:

package cn.ganlixin.timer;

import cn.ganlixin.task.MyTask;

import org.junit.Test;

import java.text.ParseException;

import java.util.Timer;

public class TestTimer {

@Test

public void testTimerDemo() throws InterruptedException {

// 创建一个定时器

Timer timer = new Timer();

// 5秒之后执行任务,只执行一次,执行MyTask的run方法

// schedule(TimerTask task, long delay)

timer.schedule(new MyTask(), 5 * 1000L);

// 让当前线程阻塞,等待上面的任务执行

Thread.sleep(10000);

}

}

Timer有几个可以设置任务执行的方法:

// 在deley毫秒毫秒后,开始执行task,只执行一次

void schedule(TimerTask task, long delay)

// 在deley毫秒毫秒后,开始执行task,之后每隔period毫秒执行一次task

void schedule(TimerTask task, long delay, long period)

// 在date时刻,开始执行task,只执行一次

void schedule(TimerTask task, Date date)

// 在date时刻,开始执行task,之后每隔period毫秒执行一次task

void schedule(TimerTask task, Date firstTime, long period)

// 和schedule(TimerTask task, long delay, long period)一样,但是以固定速率执行

scheduleAtFixedRate(TimerTask task, long delay, long period)

// 和schedule(TimerTask task, Date firstTime, long period)一样,但是以固定速率执行

scheduleAtFixedRate(TimerTask task, Date firstTime, long period)

schedule和scheduleAtFixRate有一些区别。

2.2、schedule

1、当首次计划执行时间早于当前时间,比如要求在1980年1月1日凌晨执行某个任务

对于这种情况,启动定时任务后,会立即执行任务。下面是例子:

package cn.ganlixin.timer;

import org.junit.Test;

import java.text.ParseException;

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.Timer;

import java.util.TimerTask;

public class TestTimer {

@Test

public void testStartBefore() throws InterruptedException, ParseException {

Timer timer = new Timer();

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

System.out.println("当前时间:" + dateFormat.format(new Date()));

Date date = dateFormat.parse("2019-01-01 01:00:00"); // 开始时间为过去

timer.schedule(new TimerTask() {

@Override

public void run() {

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

Date scheduledExecuteTime = new Date(scheduledExecutionTime());

System.out.println("预计执行任务时间:" + dateFormat.format(scheduledExecuteTime));

System.out.println("开始任务:" + dateFormat.format(new Date()));

try {

Thread.sleep(10000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("完成任务:" + dateFormat.format(new Date()));

}

}, date);

// 让当前线程阻塞,等待上面的任务执行

Thread.sleep(100000);

}

}

运行输出:

当前时间:2019-03-07 07:56:47

预计执行任务时间:2019-01-01 01:00:00

开始任务:2019-03-07 07:56:47

完成任务:2019-03-07 07:56:57

2、首次执行时间在当前时间之后,但是执行时间超过了period(周期)

比如,有一个任务在4秒后启动,每3秒执行1次,任务每次执行要10秒,此时,因为执行任务所需时间超过了周期时间,所以一次任务执行完后,立即执行下一次任务;

package cn.ganlixin.timer;

import org.junit.Test;

import java.text.ParseException;

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.Timer;

import java.util.TimerTask;

public class TestTimer {

@Test

public void testTimerDemo() throws InterruptedException, ParseException {

// 创建一个定时器

Timer timer = new Timer();

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

System.out.println("当前时间:" + dateFormat.format(new Date()));

timer.schedule(new TimerTask() {

@Override

public void run() {

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

Date scheduledExecuteTime = new Date(scheduledExecutionTime());

System.out.println("预计执行任务时间:" + dateFormat.format(scheduledExecuteTime));

System.out.println("开始任务:" + dateFormat.format(new Date()));

try {

Thread.sleep(10000); // 休眠10秒,模拟任务执行耗时

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("完成任务:" + dateFormat.format(new Date()));

System.out.println("-----------------------------------------");

}

}, 4 * 1000L, 3 * 1000L);

// 让当前线程阻塞,等待上面的任务执行

Thread.sleep(100000);

}

}

运行结果:

当前时间:2019-03-07 08:14:40

预计执行任务时间:2019-03-07 08:14:44

开始任务:2019-03-07 08:14:44

完成任务:2019-03-07 08:14:54

-----------------------------------------

预计执行任务时间:2019-03-07 08:14:54

开始任务:2019-03-07 08:14:54

完成任务:2019-03-07 08:15:04

-----------------------------------------

预计执行任务时间:2019-03-07 08:15:04

开始任务:2019-03-07 08:15:04

完成任务:2019-03-07 08:15:14

-----------------------------------------

预计执行任务时间:2019-03-07 08:15:14

开始任务:2019-03-07 08:15:14

.........

2.3、scheduleAtFixRate

1、当首次计划执行时间早于当前时间,那么scheduleAtFixRate会将错过的这段时间中,本应该执行的任务“补”回来。

package cn.ganlixin.timer;

import org.junit.Test;

import java.text.ParseException;

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.Timer;

import java.util.TimerTask;

public class TestTimer {

@Test

public void testTimerDemo() throws InterruptedException, ParseException {

// 创建一个定时器

Timer timer = new Timer();

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

System.out.println("当前时间:" + dateFormat.format(new Date()));

Date date = dateFormat.parse("2019-01-01 01:00:00"); // 开始时间为过去

timer.scheduleAtFixedRate(new TimerTask() {

@Override

public void run() {

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

Date scheduledExecuteTime = new Date(scheduledExecutionTime());

System.out.println("预计执行任务时间:" + dateFormat.format(scheduledExecuteTime));

System.out.println("开始任务:" + dateFormat.format(new Date()));

try {

Thread.sleep(10000); // 休眠10秒,模拟任务执行耗时

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("完成任务:" + dateFormat.format(new Date()));

System.out.println("-----------------------------------------");

}

}, date, 3 * 1000L);

// 让当前线程阻塞,等待上面的任务执行

Thread.sleep(100000);

}

}

2、首次执行时间在当前时间之后,但是执行时间超过了period(周期),此时会将错过的任务补回来

package cn.ganlixin.timer;

import org.junit.Test;

import java.text.ParseException;

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.Timer;

import java.util.TimerTask;

public class TestTimer {

@Test

public void testTimerDemo() throws InterruptedException, ParseException {

// 创建一个定时器

Timer timer = new Timer();

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

System.out.println("当前时间:" + dateFormat.format(new Date()));

timer.scheduleAtFixedRate(new TimerTask() {

@Override

public void run() {

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

Date scheduledExecuteTime = new Date(scheduledExecutionTime());

System.out.println("预计执行任务时间:" + dateFormat.format(scheduledExecuteTime));

System.out.println("开始任务:" + dateFormat.format(new Date()));

try {

Thread.sleep(10000); // 休眠10秒,模拟任务执行耗时

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("完成任务:" + dateFormat.format(new Date()));

System.out.println("-----------------------------------------");

}

}, 4 * 1000L, 3 * 1000L);

// 让当前线程阻塞,等待上面的任务执行

Thread.sleep(100000);

}

}

运行输出

当前时间:2019-03-07 08:26:53

预计执行任务时间:2019-03-07 08:26:57

开始任务:2019-03-07 08:26:57

完成任务:2019-03-07 08:27:07

-----------------------------------------

预计执行任务时间:2019-03-07 08:27:00

开始任务:2019-03-07 08:27:07

完成任务:2019-03-07 08:27:17

-----------------------------------------

预计执行任务时间:2019-03-07 08:27:03

开始任务:2019-03-07 08:27:17

完成任务:2019-03-07 08:27:27

-----------------------------------------

预计执行任务时间:2019-03-07 08:27:06

开始任务:2019-03-07 08:27:27

完成任务:2019-03-07 08:27:37

三、Quartz

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值