前言:Java定时器目前主要有3种实现方式:JDK组件,Spring Task,Quartz框架。

1. JDK组件
(1) java.util.TimerTask


MyTimerTask.java:

public class MyTimerTask extends TimerTask {
  @Override
  public void run() {
    System.out.println("MyTimerTask, now: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
  }   public static void main(String[] args) {
    Timer timer = new Timer();
    timer.schedule(new MyTimerTask(), 1000, 1000);
    //timer.cancel(); //停止调度器
  }
}

(2) java.util.concurrent.ScheduledThreadPoolExecutor(JDK5.0+之后推荐使用)


MyScheduledTask.java:

public class MyScheduledTask implements Runnable {
  public void run() {
    System.out.println("my scheduled task, now: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
  }
}

MyScheduledExecutor.java:

public class MyScheduledExecutor {
  public static void main(String[] args) {
    ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10);
    ScheduledFuture future = executor.scheduleWithFixedDelay(new MyScheduledTask(), 1000, 1000, TimeUnit.MILLISECONDS);
    //future.cancel(true); // 停止定时任务,Timer不能停止定时任务,只能关闭调度器
    //executor.shutdown(); // 关闭调度器
  }
}

比较:java.util.concurrent.ScheduledThreadPoolExecutor比java.util.Timer更加灵活和高效。

2. Spring Task
(1) xml配置方式实现
TaskJob.java:

@Service
public class TaskJob {
  public void job1() {
    System.out.println("指定Spring定时任务1, now: " + new SimpleDateFormat("yyy-MM-dd HH:mm:ss").format(new Date()));
  }
}

spring.xml:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:task="http://www.springframework.org/schema/task"
...
xsi:schemaLocation="
...
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd">
  <!-- 自动注入定时任务组件 -->
  <context:component-scan base-package="xxx" />   <!-- 定义定时任务调度策略 -->
  <task:scheduled-tasks>
    <task:scheduled ref="taskJob" method="job1" cron="0/1 * * * * ?" />
  </task:scheduled-tasks>
</beans>

(2) 注解方式实现
TaskJob2.java:

@Component
public class TaskJob2 {
  /**
  * 每隔一秒执行一次
  */
  @Scheduled(cron="0/1 * * * * ?")
  public void job2() {
    System.out.println("注解方式使用spring定时任务框架, now: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
  }
}

spring.xml:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task"
...
xsi:schemaLocation="
...
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd">
  <!-- 自动注入定时任务组件 -->
  <context:component-scan base-package="xxx" />   <!-- 启动注解方式的定时任务 -->
  <task:annotation-driven />
</beans>

3. Quartz
Quartz是一个开源的,功能非常丰富的定时器框架,详见:http://www.quartz-scheduler.org/
Quartz可以独立使用,也可以集成在Spring框架中,详见:http://projects.spring.io/spring-framework/

(1) 独立使用Quartz(详见Quartz官方示例):
pom.xml:

<dependencies>
  <dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.2.1</version>
  </dependency>
  <dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz-jobs</artifactId>
    <version>2.2.1</version>
  </dependency>
</dependencies>

定义定时任务,MyJob.java:

public class MyJob implements Job {
  public void execute(JobExecutionContext arg0) throws JobExecutionException {
    System.out.println("执行Quartz定时任务实现, now: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
  }
}

调度定时任务,MyJobSheduler:

public class MyJobSheduler {
  public static void main(String[] args) {
    try {
      JobDetail job = JobBuilder.newJob(MyJob.class).withIdentity("myJob").build();
      Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1")
                .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1).repeatForever())
                .build();
      Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
      scheduler.scheduleJob(job, trigger);
      scheduler.start();
      } catch (SchedulerException e) {
        e.printStackTrace();
      }
    }
}

(2) Spring集成Quartz
如:http://docs.spring.io/spring/docs/5.0.0.M4/spring-framework-reference/htmlsingle/#scheduling-quartz

【实现比较】

实现方式                   
优点 缺点
JDK组件 无需引入第三方依赖,控制灵活 仅支持简单任务调度,不支持指定日期等复杂定时任务
SpringTask 功能相对JDK方式全面(简单或指定日期等复杂任务调度),支持注解和配置2种方式

Spring 3.x及以上版本才支持,详见: http://www.springframework.org/schema/task,无法灵活控制任务启动或停止

Quartz  开源,功能全面且强大(简单或指定日期等复杂任务调度),可独立使用,也可以与Spring集成 必须在项目中引入quartz依赖 在项目中必须引入quartz依赖

【使用总结】
1. J2EE项目
    -- 未依赖Spring框架,建议使用Quartz。
    -- 引入了Spring 3.x+,如果仅需要简单定时任务控制,建议使用Spring Task;否则建议使用Quartz。
    -- 特别地,在Spring Boot项目中,根据需求可以灵活选择JDK,Spring Task或者Quartz。

2. 非J2EE项目
    -- 简单定时任务控制,建议使用JDK实现:java.util.concurrent.ScheduledThreadPoolExecutor;否则建议使用Quartz。

附:在Linux环境下,可以直接使用crontab程序实现简单的定时任务,比如定时全量备份MySQL数据库。

详见:https://wiki.archlinux.org/index.php/Cron_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)

crontab在线调试工具:https://crontab.guru/

【参考】
http://gong1208.iteye.com/blog/1773177                            Spring定时任务的几种实现
http://www.cnblogs.com/liuyitian/p/4108391.html                Spring cron 表达式
http://blog.csdn.net/ethanzhao/article/details/4406017       Linux crontab 命令格式与详细例子

java定时器实现总结的更多相关文章

  1. java定时器和多线程实践记录

    这几天因为需要测试mongodb读写分离的问题,因此写了个定时查询程序,并且用到了多线程,以达到定时启动多个线程查询数据库的效果,下边代码记录备忘: package timmer; import ja ...

  2. java定时器,Spring定时器和Quartz定时器

    一.java定时器的应用 其实java很早就有解决定时器任务的方法了,java提供了了类java.util.TimerTask类基于线程的方式来实现定时任务的操作,然后再提供java.util.Tim ...

  3. Java定时器:Timer

    项目中往往会遇到需要定时的任务,例如订单,当用户在某个规定时间内没有操作订单时,订单状态将会发生改变. 那么在这种情况下,我们会用到定时器. 举例: import java.util.Timer; / ...

  4. Java定时器应用

    在Java多线程中,有的时候,我们需要按照指定间隔时间来执行一些任务,这时,我们就要用到定时器.我们在这里以Java中的Timer定时器为例,演示定时器的应用. 请看下述代码: import java ...

  5. Java定时器TimeTask

    package com.alan.timer; import java.util.Calendar;import java.util.Date;import java.util.Timer;impor ...

  6. Java定时器Timer

    Java定时器Timer在JDK库中,Timer类主要负责计划任务的功能,也就是在指定的时开始执行某一个任务.Timer类的主要作用就是设置计划任务,但封装任务的类却是TimerTask类,执行计划任 ...

  7. [Java定时器]用Spring Task实现一个简单的定时器.

    今天做一个项目的的时候需要用到定时器功能.具体需求是: 每个月一号触发一次某个类中的方法去拉取别人的接口获取上一个月份车险过期的用户.如若转载请附上原文链接:http://www.cnblogs.co ...

  8. 关于java 定时器的使用总结

    直接上代码,代码中有注释(代码中还有一些本人的其他测试,读者可以忽略不计).读者在代码中发现了bug,欢迎指正. package j2se.system.test; import java.text. ...

  9. java定时器的使用

    定时器类Timer在java.util包中.使用时,先实例化,然后使用实例的schedule(TimerTask task, long delay)方法,设定指定的任务task在指定的延迟delay后 ...

随机推荐

  1. BZOJ 2069: [POI2004]ZAW(Dijkstra + 二进制拆分)

    题意 给定一个有 \(N\) 个点 \(M\) 条边的无向图, 每条无向边 最多只能经过一次 . 对于边 \((u, v)\) , 从 \(u\) 到 \(v\) 的代价为 \(a\) , 从 \(v ...

  2. One Person Game ZOJ - 3329(期望dp, 数学)

    There is a very simple and interesting one-person game. You have 3 dice, namely Die1, Die2 and Die3. ...

  3. mysql 远程连接 10038

    1,先确认本地是否能连上本地能连上就对用户进行授权 mysql>grant all privileges on *.* to 'root'@'%' identified by 'youpassw ...

  4. OpenLayers学习笔记(七)— 类似比例尺的距离环(一)

    openlayers 3 地图上创建一个距离环,始终以地图中心为中心,每个环之间的距离类似比例尺,随地图缩放而变化. 添加具有覆盖整个范围的特征的虚拟层,其可以被设置为围绕地图中心的环.注意,根据地图 ...

  5. 关于数据结构,剑指offer上面的

    我很喜欢那些javascript解决的编程题,感觉非常的有意思.我在博客园上面看到了一个同学的博客,他一共发了34篇剑指offer的编程题,还给出了非常详细的解答. 接下来的工作,我做的就是搬运工,不 ...

  6. 第一篇-Win10打开txt文件出现中文乱码

    如果刚开始安装的是英文的Win10系统,那么打开txt文件时很容易出现乱码问题.包括打开cmd窗口,也是不能显示中文的.当然,麻烦的处理方法是: 在cmd中想要显示中文:先输入chcp 936,之后中 ...

  7. HDU 1880 魔咒词典 (Hash)

    魔咒词典 Time Limit: 8000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  8. 解决access 导出 excel 字段截断错误的问题

    解决方法:这个问题通过从EXCEL中导入外部数据,也就是ACCESS数据可以解决. 1.选择导入数据 2.点击选择数据源 选择需要导入的access数据源

  9. Luogu P2580 于是他错误的点名开始了 Trie树 字典树

    字典树裸题.每次插入询问串,查询的时候拿出来直接查,信息保留在节点上. #include <bits/stdc++.h> using namespace std; char s[51]; ...

  10. window下域名解析系统DNS诊断命令nslookup详解

    Ping指令我们很熟悉了,它是一个检查网络状况的命令,在输入的参数是域名的情况下会通过DNS进行查询,但只能查询A记录和CNAME(别名)记录,还会返回域名是否存在,其他的信息都是没有的.如果你需要对 ...