Java 定时任务 & 任务调度
任务调度是指基于 给定时间点,给定时间间隔 或者 给定执行次数 自动执行任务。
方式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 实现复杂任务调度
Timer和 ScheduledExecutor 都仅能提供基于开始时间与重复间隔的任务调度,不能胜任更加复杂的调度需求。
比如,设置每星期二的 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 实现方法与比较
作者:专职跑龙套
链接:https://www.jianshu.com/p/aa7b7f50b4b0
來源:简书
Java 定时任务 & 任务调度的更多相关文章
- Quartz实现JAVA定时任务的动态配置
什么是动态配置定时任务? 首先说下这次主题,动态配置.没接触过定时任务的同学可以先看下此篇:JAVA定时任务实现的几种方式 定时任务实现方式千人千种,不过基础的无外乎 1.JDK 的Timer类 2. ...
- Java定时任务工具详解之Timer篇
Java定时任务调度工具详解 什么是定时任务调度? ◆ 基于给定的时间点,给定的时间间隔或者给定的执行次数自动执行的任务. 在Java中的定时调度工具? ◆ Timer ◆Quartz T ...
- java定时任务调度框架
java定时任务目前主要有三种: Java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务.使用这种方式可以让你的程序按照某一个频度执行,但不能在 ...
- atititt.java定时任务框架选型Spring Quartz 注解总结
atititt.java定时任务框架选型Spring Quartz 总结 1. .Spring Quartz (ati recomm) 1 2. Spring Quartz具体配置 2 2.1. 增 ...
- java定时任务
java定时任务实现方法: public class TimingTask { private static int count = 0; private static SpiderService s ...
- [转][JAVA]定时任务之-Quartz使用篇
[BAT][JAVA]定时任务之-Quartz使用篇 定时任务之-Quartz使用篇 Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与 ...
- Java定时任务器
java定时任务,每天定时执行任务.以下是这个例子的全部代码. public class TimerManager { //时间间隔 private static final long PERIOD_ ...
- java——定时任务
java定时任务直接看代码 public void timeTask(){ Timer timer = new Timer(); timer.schedule(new TimerTask() { pu ...
- 通过源码分析Java开源任务调度框架Quartz的主要流程
通过源码分析Java开源任务调度框架Quartz的主要流程 从使用效果.调用链路跟踪.E-R图.循环调度逻辑几个方面分析Quartz. github项目地址: https://github.com/t ...
随机推荐
- wifi驱动移植
目标板:Hi3518 内核版本:linux3.0.8 1.修改makefile #PLATFORM = PC //注释掉 PLATFORM = HI3518 //支持平台 ifeq ($(PLAT ...
- Leetcode 之Binary Tree Postorder Traversal(47)
中序遍历二叉搜索树,得到的是一个有序的结果,找出其中逆序的地方就可以了.如果逆序的地方相邻,只需把逆序的相换即可:如果不相邻,则需要找到第二个逆序对的 第二个元素再做交换. 定义两个指针p和q来指定需 ...
- ltsdangerous加密解密
前言 在做QQ第三方登录时,用户跳转到QQ登录界面登录成功后,会在URL返回一个code参数.前端把code发送给后端.后端收到后,会查询出openid.然后判断openid是否存在,如果存在就可以绑 ...
- 【python】pymongo中正则查询时的转义问题
在查询mongo时用到了正则查询 设字符串为 str = '/ab/cd.ef?g=' 直接用正则查询没有匹配. collection.find({"re":{'$regex' ...
- gulp-babel,es6转es5
npm install --save-dev gulp-babel npm install --save-dev babel-preset-es2015 var gulp = require(&quo ...
- 追忆似水流年sed
sed是一种非交互式的流编辑器,默认情况下并不会修改源文件内容,只是把命令的结果输出处理单位:行功能:查找替换.添加.插入.删除适用场景:常规编辑器难以胜任的文本:大文件(几百兆):有规律的文本修改操 ...
- centos7.5&ubuntu18.10安装Google浏览器
一.手动安装 1. 下载 rpm 包https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm 2. 安装依赖 ...
- mac安装jdk1.8
一. http://www.oracle.com/technetwork/java/javase/downloads/index.html 去jdk官网下载 二.安装 一路傻瓜式安装,下一步下一步 三 ...
- 每一对顶点间最短路径的Floyd算法
Floyd思想可用下式描述: A-1[i][j]=gm[i][j] A(k+1)[i][j]=min{Ak[i][j],Ak[i][k+1]+Ak[K+1][j]} -1<=k<=n ...
- 【前端必备】三、JS篇
1.运算符与隐式类型转换 类型判断: typeof constructor.toString().indexOf() NaN是numberArray.Date.Null都是Objectfunction ...