任务调度是指基于 给定时间点给定时间间隔 或者 给定执行次数 自动执行任务。

方式1:通过 Thread 来实现

例如如下的代码,可以每隔 1000 毫秒做一次打印操作。

public class Job_Schedule_Test1 {
public static void main(String[] args) {
new JobThread().start();
}
} class JobThread extends Thread {
public void run() {
while (true) {
System.out.println("Test: " + Calendar.getInstance().getTime()); try {
Thread.sleep(1000);
} catch (Exception e) {
}
}
}
}

输出如下:

Test: Wed Feb 22 14:33:57 CST 2017
Test: Wed Feb 22 14:33:58 CST 2017
Test: Wed Feb 22 14:33:59 CST 2017
Test: Wed Feb 22 14:34:00 CST 2017
Test: Wed Feb 22 14:34:01 CST 2017

方式2:通过 Timer 来实现

  • 自定义一个任务,继承于 TimerTask,重写 run 方法
  • 利用 java.util.Timer 实现任务调度
public class Job_Schedule_Test2 {
public static void main(String[] args) {
Timer timer = new Timer();
long delay = 2000;
long interval = 1000; // 从现在开始 2 秒钟之后启动,每隔 1 秒钟执行一次
timer.schedule(new JobTask(), delay, interval);
}
} class JobTask extends TimerTask {
public void run() {
System.out.println("Test: " + Calendar.getInstance().getTime());
}
}

输出如下:

Test: Wed Feb 22 15:02:15 CST 2017
Test: Wed Feb 22 15:02:16 CST 2017
Test: Wed Feb 22 15:02:17 CST 2017
Test: Wed Feb 22 15:02:18 CST 2017
Test: Wed Feb 22 15:02:19 CST 2017

Timer 的设计核心是一个 TaskList 和一个 TaskThread
Timer 将接收到的任务丢到自己的 TaskList 中,TaskList 按照 Task 的最初执行时间进行排序。TimerThread 在创建 Timer 时会启动成为一个守护线程。这个线程会轮询所有任务,找到一个最近要执行的任务,然后休眠,当到达最近要执行任务的开始时间点,TimerThread 被唤醒并执行该任务。之后 TimerThread 更新最近一个要执行的任务,继续休眠。

Timer 的优点在于简单易用,但由于所有任务都是由同一个线程来调度,因此所有任务都是串行执行的,同一时间只能有一个任务在执行,前一个任务的延迟或异常都将会影响到之后的任务。
例如我们指定每隔 1000 毫秒执行一次任务,但是可能某个任务执行花了 5000 毫秒,因此导致后续的任务并不能按时启动执行。

方式3:通过 ScheduledExecutorService 来实现

鉴于 Timer 的上述缺陷,Java 5 推出了基于线程池设计的 ScheduledExecutorService
其设计思想是,每一个被调度的任务都会 由线程池中一个线程去执行,因此任务是并发执行的,相互之间不会受到干扰。
需要注意的是,只有当任务的执行时间到来时,ScheduledExecutorService 才会真正启动一个线程,其余时间 ScheduledExecutorService 都是在轮询任务的状态。

public class Job_Schedule_Test3 {
public static void main(String[] args) {
ScheduledExecutorService service = Executors.newScheduledThreadPool(10);
long delay = 2;
long interval = 1; // 从现在开始 2 秒钟之后启动,每隔 1 秒钟执行一次
service.scheduleAtFixedRate(
new JobTask2(), delay,
interval, TimeUnit.SECONDS);
}
} class JobTask2 implements Runnable {
public void run() {
System.out.println("Test: " + Calendar.getInstance().getTime());
}
}

输出如下:

Test: Wed Feb 22 15:19:05 CST 2017
Test: Wed Feb 22 15:19:06 CST 2017
Test: Wed Feb 22 15:19:07 CST 2017
Test: Wed Feb 22 15:19:08 CST 2017
Test: Wed Feb 22 15:19:09 CST 2017

用 ScheduledExecutorService 和 Calendar 实现复杂任务调度

TimerScheduledExecutor 都仅能提供基于开始时间与重复间隔的任务调度,不能胜任更加复杂的调度需求。
比如,设置每星期二的 16:38:10 执行任务。我们可以借助 Calendar 间接实现该功能。
其核心在于根据当前时间推算出最近一个星期二 16:38:10 的绝对时间,然后计算与当前时间的时间差,作为调用 ScheduledExceutor 函数的参数。

具体参见 几种任务调度的 Java 实现方法与比较

方式4:通过 Quartz 来实现

Quartz is a richly featured, open source job scheduling library that can be integrated within virtually any Java application - from the smallest stand-alone application to the largest e-commerce system. Quartz can be used to create simple or complex schedules for executing tens, hundreds, or even tens-of-thousands of jobs; jobs whose tasks are defined as standard Java components that may execute virtually anything you may program them to do.

示例如下:

public class QuartzJob implements org.quartz.Job {
public QuartzJob() {
} public void execute(JobExecutionContext arg0) throws JobExecutionException {
System.out.println("Test: " + Calendar.getInstance().getTime());
}
} import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import static org.quartz.JobBuilder.*;
import static org.quartz.TriggerBuilder.*;
import static org.quartz.SimpleScheduleBuilder.*; public class Job_Schedule_Test4 {
public static void main(String[] args) throws SchedulerException {
// Grab the Scheduler instance from the Factory
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); // define the job and tie it to our MyJob class
JobDetail job = newJob(QuartzJob.class)
.withIdentity("job1", "group1")
.build(); // Trigger the job to run now, and then repeat every 40 seconds
Trigger trigger = newTrigger()
.withIdentity("trigger1", "group1")
.startNow()
.withSchedule(simpleSchedule()
.withIntervalInSeconds(1)
.repeatForever())
.build(); // Tell quartz to schedule the job using our trigger
scheduler.scheduleJob(job, trigger); // and start it off
scheduler.start();
}
}

方式5:通过 JCronTab 来实现

具体参见 几种任务调度的 Java 实现方法与比较


引用:
Java实现定时任务的三种方法
几种任务调度的 Java 实现方法与比较

作者:专职跑龙套
链接:https://www.jianshu.com/p/aa7b7f50b4b0
來源:简书

Java 定时任务 & 任务调度的更多相关文章

  1. Quartz实现JAVA定时任务的动态配置

    什么是动态配置定时任务? 首先说下这次主题,动态配置.没接触过定时任务的同学可以先看下此篇:JAVA定时任务实现的几种方式 定时任务实现方式千人千种,不过基础的无外乎 1.JDK 的Timer类 2. ...

  2. Java定时任务工具详解之Timer篇

    Java定时任务调度工具详解 什么是定时任务调度? ◆ 基于给定的时间点,给定的时间间隔或者给定的执行次数自动执行的任务. 在Java中的定时调度工具? ◆ Timer       ◆Quartz T ...

  3. java定时任务调度框架

    java定时任务目前主要有三种: Java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务.使用这种方式可以让你的程序按照某一个频度执行,但不能在 ...

  4. atititt.java定时任务框架选型Spring Quartz 注解总结

    atititt.java定时任务框架选型Spring Quartz 总结 1. .Spring Quartz  (ati recomm) 1 2. Spring Quartz具体配置 2 2.1. 增 ...

  5. java定时任务

    java定时任务实现方法: public class TimingTask { private static int count = 0; private static SpiderService s ...

  6. [转][JAVA]定时任务之-Quartz使用篇

    [BAT][JAVA]定时任务之-Quartz使用篇 定时任务之-Quartz使用篇 Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与 ...

  7. Java定时任务器

    java定时任务,每天定时执行任务.以下是这个例子的全部代码. public class TimerManager { //时间间隔 private static final long PERIOD_ ...

  8. java——定时任务

    java定时任务直接看代码 public void timeTask(){ Timer timer = new Timer(); timer.schedule(new TimerTask() { pu ...

  9. 通过源码分析Java开源任务调度框架Quartz的主要流程

    通过源码分析Java开源任务调度框架Quartz的主要流程 从使用效果.调用链路跟踪.E-R图.循环调度逻辑几个方面分析Quartz. github项目地址: https://github.com/t ...

随机推荐

  1. cpu占用高 20180108

    1.top 中的mysql占用高,在mysql中开启慢查询,用tail -f  监控慢查询日志,发现是有表的索引不合理: 2.top 中的php_fpm的进程数高,修改了一下php_fpm的配置文件p ...

  2. Network Embedding

    网络表示 网络表示学习(DeepWalk,LINE,node2vec,SDNE) https://blog.csdn.net/u013527419/article/details/76017528 网 ...

  3. 步骤一:下载jdk并安装和配置java环境变量

    1.下载JDk地址: http://download.eclipse.org/oomph/jre/?vm=1_1_7_0_64_0 2.进入下载页面(下载的是jdk7),点击:Oracle JDK1. ...

  4. 10:django 模板语言

    Django的模板语言的目的是取得力量和易用性之间的平衡,与其他的模板语言相比,django模板语言显得更简单,更专一, django模板系统由模板,变量,过滤器,标签,注释等主要部分组成 模板 一个 ...

  5. mysql远程访问cannot connect(10038) 问题解决的过程

    今天用Navicat访问虚拟机上的mysql,无法访问报cannot connect(10038). 首先看是否可以telnet,本机cmd,telnet 192.168.209.128 3306,结 ...

  6. python和语法糖

       语法糖(syntactic sugar)是指编程语言中可以更容易的表达一个操作的语法,它可以使程序员更加容易去使用这门语言:操作可以变得更加清晰.方便,或者更加符合程序员的编程习惯.(百度百科的 ...

  7. grunt 自定义任务实现js文件的混淆及加密

    //自定义任务 module.exports = function (grunt) { // 项目配置 var http = require('http'); var qs = require('qu ...

  8. ubuntu16.04 安装composer和 laravel

    一.安装composer $ sudo apt-get update $ sudo apt-get install wget 下载composer.phar $ wget https://getcom ...

  9. BZOJ2120/洛谷P1903 [国家集训队] 数颜色 [带修改莫队]

    BZOJ传送门:洛谷传送门 数颜色 题目描述 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会向你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R ...

  10. Linux命令之rlogin

    rlogin [-8EKLdx] [-e char] [-l username] host rlogin在远程主机host上开始一个终端会话. (1).选项 -8 选项允许进行8位的输入数据传送:否则 ...