在线corn表达式

1. 总结常见的实现定时任务的几种方法

  • thread实现 【原理:通过创建一个线程,让他在while循环里面一直运行,用sleep() 方法让其休眠从而达到定时任务的效果。】
  • Timer类
  • ScheduledExcecutorService类
  • 使用spring的 spring-task 实现
  • Quartz

以下演示几种实现方式:每隔一秒打印一次hello world

1.1 thread实现

public static void main(String[] args) {
final long timeInterval = 1000; Runnable runnable = new Runnable() {
@Override
public void run() {
while (true) {
System.out.println("hello world");
try {
Thread.sleep(timeInterval);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}; Thread thread = new Thread(runnable);
thread.start();
}

1.2 Timer类实现

Timer是jdk中自带的一个定时器工具,使用的时候会在主线程之外起一个单独的线程执行指定的计划任务,可以指定执行一次或者反复执行多次。但封装任务的类是TimerTask类(实际该类是一个抽象类,执行任务的代码要放在该类的子类中)。

TimerTask是一个实现了Runnable接口的抽象类,代表一个可以被Timer执行的任务。

构造方法:



成员方法:

public static void main(String[] args) {
TimerTask task = new TimerTask() {
@Override
public void run() {
System.out.println("Hello!Word!");
}
}; Timer timer = new Timer();
long delay = 0;
long intevalPeriod = 1 * 1000;
timer.scheduleAtFixedRate(task, delay, intevalPeriod);
}

schedule 与 scheduleAtFixedRate区别:

schedule会保证任务的间隔是按照定义的period参数严格执行的,如果某一次调度时间比较长,那么后面的时间会顺延,保证调度间隔都是period。
scheduleAtFixedRate是严格按照调度时间来的,如果某次调度时间太长了,那么会通过缩短间隔的方式保证下一次调度在预定时间执行。

线程安全, 但只会单线程执行, 如果执行时间过长, 就错过下次任务了, 抛出异常时, timerWork会终止

启动和取消任务是可以控制的

1.3 ScheduledExcecutorService类实现

ScheduledExecutorService是JDK1.5以后java.util.concurrent中的一个接口, 用于实现定时任务。

public static void main(String[] args) {
Runnable r1 = new Runnable() {
public void run() {
System.out.println("Hello Word");
}
};
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
// 第二个参数为首次执行的延时时间,第三个参数为定时执行的间隔时间
service.scheduleAtFixedRate(r1, 3, 1, TimeUnit.SECONDS);// 3秒后开始执行
}

他是通过线程池的方式执行任务,可以多线程执行。

启动和取消任务是可以控制的

可以设定第一次的延迟时间

1.4 使用spring提供的 spring-task 实现

a) 只需要导入web的starter依赖

b) 在启动类上添加 @EnableScheduling 注解

c) 用 @Scheduled 注解开启一个定时任务。

@Component
public class SchedulerTask {
private int count = 0; /**
* @Author Smith
* @Description 设置每1秒执行一次
* @Date 14:23 2019/1/24
* @Param
* @return void
**/
@Scheduled(cron = "*/1 * * * * ?") // 基于cron表达式实现
private void process(){
System.out.println("hello world " + (count++));
}
}

@Scheduled 该注解的常用参数说明【不基于cron表达式实现的时候】:

fixedRate 表示任务执行之间的时间间隔,具体是指两次任务的开始时间间隔,即第二次任务开始时,第一次任务可能还没结束。

fixedDelay 表示任务执行之间的时间间隔,具体是指本次任务结束到下次任务开始之间的时间间隔。

initialDelay 表示首次任务启动的延迟时间。

所有时间的单位都是毫秒。

1.5 Quartz

参考

源码

Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。

Quartz默认是多线程异步执行,单个任务时,在上一个调度未完成时,下一个调度时间到时,会另起一个线程开始新的调度。

Quartz支持集群定时任务

Quartz与Spring Task区别

  • Quartz默认多线程异步执行,Task默认单线程同步执行。
  • Quartz单个任务时,在上一个调度未完成时,下一个调度时间到时,会另起一个线程开始新的调度。Task单个任务时,当前次的调度完成后,再执行下一次任务调度。
  • Quartz多个任务时,任务之间没有直接影响,多任务执行的快慢取决于CPU的性能。Task多个任务时,一个任务执行完成后才会执行下一个任务。若需要任务能够并发执行,需手动设置线程池
  • Quartz可以采用集群方式,分布式部署到多台机器,分配执行定时任务

两者对比总结:

1、实现,Task注解实现方式,比较简单。Quartz需要手动配置Jobs。

2、任务执行,Task默认单线程串行执行任务,多任务时若某个任务执行时间过长,后续任务会无法及时执行。Quartz采用多线程,无这个问题。

3、调度,Task采用顺序执行,若当前调度占用时间过长,下一个调度无法及时执行;

4、Quartz采用异步,下一个调度时间到达时,会另一个线程执行调度,不会发生阻塞问题,但调度过多时可能导致数据处理异常

5、部署,Quartz可以采用集群方式,分布式部署到多台机器,分配执行定时任务

Quartz 核心概念:

a) Job 表示一个工作,要执行的具体内容。此接口中只有一个方法。Task多个任务时,一个任务执行完成后才会执行下一个任务。若需要任务能够并发执行,需手动设置线程池。

void execute(JobExecutionContext context)

b) JobDetail 表示一个具体的可执行的调度程序,Job 是这个可执行程调度程序所要执行的内容,另外 JobDetail 还包含了这个任务调度的方案和策略。

c) Trigger 代表一个调度参数的配置,什么时候去调。

d) Scheduler 代表一个调度容器,一个调度容器中可以注册多个 JobDetail 和 Trigger。当 Trigger 与 JobDetail 组合,就可以被 Scheduler 容器调度了。

Spring Boot整合Quartz:

  1. 导入Quartz依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
  1. 编写任务类
public class Task implements Job {

        // 任务类不能直接注入Bean,若想注入Bean需要配置第4步
@Autowired
private TestService service; private void before(){
System.out.println("定时任务开始");
} @Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
service.testDemo();
System.out.println("hello quartz");
} private void afer(){
System.out.println("定时任务结束");
}
}
★ 任务类不能直接注入Bean,若想注入Bean需要配置第4步 ★
  1. 编写Quartz配置
@Configuration
public class QuartzConfig { @Bean
public JobDetailFactoryBean jobDetailFactoryBean() {
JobDetailFactoryBean factory = new JobDetailFactoryBean();
//关联我们自己的Job类
factory.setJobClass(Task.class);
return factory;
} @Bean
public CronTriggerFactoryBean cronTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean) {
CronTriggerFactoryBean factory = new CronTriggerFactoryBean();
factory.setJobDetail(jobDetailFactoryBean.getObject());
//设置触发时间
factory.setCronExpression("0/2 * * * * ?");
return factory;
} @Bean
public SchedulerFactoryBean schedulerFactoryBean(CronTriggerFactoryBean cronTriggerFactoryBean, MyAdaptableJobFactory jobFactory) {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
//关联trigger
factory.setTriggers(cronTriggerFactoryBean.getObject());
factory.setJobFactory(jobFactory);
return factory;
}
}
  1. 编写配置【用于任务类能注入我们的bean】
@Component
public class MyAdaptableJobFactory extends AdaptableJobFactory { // 可以将一个对象添加到SpringIOC 容器中,并且完成该对象注入
@Autowired
private AutowireCapableBeanFactory autowireCapableBeanFactory; /**
* 该方法需要将实例化的任务对象手动的添加到springIOC 容器中并且完成对象的注入
*/
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
Object obj = super.createJobInstance(bundle);
//将obj 对象添加Spring IOC 容器中,并完成注入
this.autowireCapableBeanFactory.autowireBean(obj);
return obj;
}
}

2 Quartz[群集环境]

使用quartz实现定时任务[单机版],若是部署多台机器,那么到了时间点,多台服务器便会同时均开始执行定时任务。

Quartz是能适用于分布式集群环境的,在同一时间只会有一台机器执行定时任务。

Quartz 中集群如何工作:

一个 Quartz 集群中的每个节点是一个独立的 Quartz 应用,它又管理着其他的节点。意思是你必须对每个节点分别启动或停止。不像许多应用服务器的集群,独立的 Quartz 节点并不与另一其的节点或是管理节点通信。Quartz 应用是通过数据库表来感知到另一应用的。离开了db将无法感知

2.1 导入依赖

<!-- spring boot2.x + quartz -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

2.2 数据库建表

到官网下载

下载之后解压,进入如下目录,创建数据库表:









11张表功能说明:

java实现定时任务解决方案的更多相关文章

  1. 完整的定时任务解决方案Spring集成+定时任务本身管理+DB持久化+集群

    完整的定时任务解决方案Spring集成+定时任务本身管理+DB持久化+集群 maven依赖 <dependency> <groupId>org.quartz-scheduler ...

  2. Java基础--定时任务Timer

    Java基础--定时任务Timer 一.Timer介绍 java.util.Timer java.util.TimerTask Timer是一个定时器类,通过该类可以为指定的定时任务进行配置.Time ...

  3. Java Scoket之java.io.EOFException解决方案

    Java Scoket之java.io.EOFException解决方案   Socket接收数据的时候,常常会抛出java.io.EOFException异常,也没有明确的原因和提示,在网上搜搜,很 ...

  4. Java基础--定时任务Timer(转载)

    Java基础--定时任务Timer 一.Timer介绍 java.util.Timer java.util.TimerTask Timer是一个定时器类,通过该类可以为指定的定时任务进行配置.Time ...

  5. Java 图片处理解决方案:ImageMagick 快速入门

    一.ImageMagick介绍 ImageMagick是一个免费的创建.编辑.合成图片的软件,可以实现图片切割.颜色替换.图片缩略图.图片水印等各种效果.ImageMagick是免费开源软件,支持大多 ...

  6. Java 图片处理解决方案:ImageMagick 快速入门教程

    文章首发于[博客园-陈树义],点击跳转到原文Java 图片处理解决方案:ImageMagick 快速入门教程. ImageMagick介绍 ImageMagick是一个免费的创建.编辑.合成图片的软件 ...

  7. Java中文乱码解决方案

    Java中文乱码解决方案   1.中文乱码解决方案,确保每个文件的默认编码是UTF-8         加入 URIEncoding="UTF-8" 代码中的设置 1>在se ...

  8. java实现定时任务的三种方法 - 转载

    java实现定时任务的三种方法 /** * 普通thread * 这是最常见的,创建一个thread,然后让它在while循环里一直运行着, * 通过sleep方法来达到定时任务的效果.这样可以快速简 ...

  9. Atitit.java jar hell解决方案-----Djava.ext.dirs in ide envi..

    Atitit.java jar hell解决方案-----Djava.ext.dirs in ide envi.. Atitit.java class flect solu jar hell use  ...

随机推荐

  1. ElasticJob 快速上手

    1.  ElasticJob 是什么 ElasticJob 是一个分布式调度解决方案,由两个相互独立的子项目 ElasticJob-Lite 和 ElasticJob-Cloud 组成. Elasti ...

  2. 【Oracle】查看oracle表空间大小及增加表空间的几种方法

    在oracle中表空间是必不可少的.但是怎么查看表空间呢 简单的查看方式是: SQL> select tablespace_name from dba_tablespaces; 想要查看表空间对 ...

  3. 【Oracle】11G 11.2.0.4 RAC环境打补丁

    一.准备工作 1,数据库环境 操作系统版本  : RedHat 7.2 x64   数据库版本    : Oracle 11.2.0.4 x64 RAC    Grid          : 11.2 ...

  4. 【Oracle】归档日志的删除操作

    [root@sha3 oracle]# rman target / Recovery Manager: Release 10.2.0.4.0 - Production on Tue Jan 20 01 ...

  5. xray—学习笔记

    长亭xray扫描器 简介 xray (https://github.com/chaitin/xray) 是从长亭洞鉴核心引擎中提取出的社区版漏洞扫描神器,支持主动.被动多种扫描方式,自备盲打平台.可以 ...

  6. 【九阳神功】Nessus 8_VM不限IP及AWVS破解版合体部署

    Nessus 8下载地址: https://moehu-my.sharepoint.com/personal/ximcx_moebi_org/_layouts/15/download.aspx?Sou ...

  7. (07)-Python3之--函数

    1.定义 函数:实现了某一特定功能.    可以重复使用. 例如: len()   功能:获取长度.input()   功能: 控制台输入print()   功能:输出 语法: def 函数名称(参数 ...

  8. VS2019中scanf返回值被忽略的问题及其解决方法

    目录 [问题](#昨天在使用Visual Studio 2019编写C语言程序时遇到了scanf返回值被忽略问题) 问题原因 方法① 方法② 方法③ 方法④ 昨天在使用Visual Studio 20 ...

  9. There are only two hard things in Computer Science: cache invalidation and naming things.

    TwoHardThings https://martinfowler.com/bliki/TwoHardThings.html https://github.com/cch123/golang-not ...

  10. Spring框架入门浅析

    一.Spring Bean的配置 在需要被Spring框架创建对象的实体类的类声明前面加注解:```@component```.这样在Spring扫描的时候,看到该注解就会在容器中创建该实体类的对象. ...