java实现周期任务_java定时任务的实现方式
本文列举常见的java定时任务实现方式,并做一定比较。
1. 循环内部sleep实现周期执行
创建一个thread,run() while循环里sleep()来实现周期性执行; 简单粗暴,作为一个初学者很容易想到。
public class Task1 {
public static void main(String[] args) {
// run in a second
final long timeInterval = 1000;
Runnable runnable = new Runnable() {
public void run() {
while (true) {
System.out.println("Hello !!");
// 使用线程休眠来实现周期执行,
try {
Thread.sleep(timeInterval);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Thread thread = new Thread(runnable);
thread.start();
}
}
2. 使用Timer类调度TimerTask任务
改进:当启动和去取消任务时可以控制; 第一次执行任务时可以指定你想要的delay时间
不足:
Timer的调度是基于绝对时间的,所以当系统时间改变时会影响Timer。
Timer只有一个工作线程,所以当一个任务执行时间很长的时候,会影响后续任务的调度。
而ScheduledThreadPoolExecutor通过线程池的方式配置更灵活。
如果任务抛出了一个未检查的异常,将会导致Timer的工作线程被终止,使Timer无法在继续运行。
import java.util.Timer;
import java.util.TimerTask;
public class HelperTest {
public static void main(String[] args) {
// 具体任务。
TimerTask task = new TimerTask() {
@Override
public void run() {
// task to run goes here
System.out.println("Hello !!!");
}
};
// Timer类可以调度任务。 Timer实例可以调度多任务,它是线程安全的。
Timer timer = new Timer();
long delay = 0;
long intevalPeriod = 1 * 1000;
// schedules the task to be run in an interval
timer.scheduleAtFixedRate(task, delay, intevalPeriod);
}
}
3. 使用j.u.c.ScheduledExecutorService定时任务接口
相比于Timer的单线程,它是通过线程池的方式来执行任务的
可以灵活的设定第一次执行任务delay时间
提供了良好的约定,以便设定执行的时间间隔
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Task3 {
public static void main(String[] args) {
ScheduledExecutorService service = new ScheduledThreadPoolExecutor(1);
// 初始化延迟0ms开始执行,每隔200ms重新执行一次任务。
ScheduledExecutorService pool = new ScheduledThreadPoolExecutor(1);
pool.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
// task to run goes here
System.out.println("Hello !");
}
}, 0, 200L, TimeUnit.MILLISECONDS);
}
实现类使用的是ScheduledThreadPoolExecutor。该类继承自ThreadPoolExecutor read more,阻塞队列使用的是DelayedWorkQueue,是ScheduledThreadPoolExecutor的内部类。
ScheduledExecutorService接口方法说明:
其中scheduleAtFixedRate和scheduleWithFixedDelay在实现定时程序时比较方便。
scheduleAtFixedRate(runnable, 0, 200L, TimeUnit.MILLISECONDS) 按指定周期执行某个任务
初始化延迟0ms开始执行,每隔200ms重新执行一次任务。
scheduleWithFixedDelay(runnable, 0, 200L, TimeUnit.MILLISECONDS) 按指定间隔执行某个任务
初始化时延时0ms开始执行,下次执行时间是(本次执行结束 + 延迟200ms)后开始执行。
schedule(Runnable command, long delay, TimeUnit unit) 在delay延时后执行一次性任务
备注:对于scheduleAtFixedRate,实际上如果当前线程阻塞执行时间t > 设置的间隔时间period,下次是在t时间后执行,并非period时间后立即开始。
ScheduledExecutorService的spring配置
>> spring.xml
>> xxx.java
@Autowired
@Qualifier("gkHeartBeatScheduler")
ScheduledExecutorService scheduledExecutorService;
scheduledExecutorService.scheduleAtFixedRate(
new Runnable() {
@Override
public void run() {
System.out.println("do sth");
}
}, 1l, 2l, TimeUnit.SECONDS);
spring ScheduledExecutorFactoryBean内部同样使用的ScheduledThreadPoolExecutor,并对其做了包装处理。
public class ScheduledExecutorFactoryBean extends ExecutorConfigurationSupport implements FactoryBean
4. @Sheduled注解方式
@Sheduled内部也使用了ScheduledThreadPoolExecutor。具体源代码可参见:spring-context包中的ScheduledAnnotationBeanPostProcessor。
用法就很简单了,举例:
pom文件引入spring-context依赖
使用注解方式配置定时任务即可
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
@EnableScheduling
public class ScheduledAnnotationDemo {
// @Scheduled和触发器元素一起添加到方法上.
@Scheduled(fixedDelay=5000)
public void doSomething() {
System.out.println("like scheduleWithFixedDelay");
}
@Scheduled(fixedRate=5000)
public void doSomething() {
System.out.println("like scheduleAtFixedRate");
}
// fixed-delay、fixed-rate任务都可以设置初始delay。
@Scheduled(initialDelay=1000, fixedRate=5000)
public void doSomething() {
// something that should execute periodically
}
// 也支持cron表达式
@Scheduled(cron = "0/5 * * * * ?")
public void doSomething() {
// something that should execute on weekdays only
System.out.println("5s执行一次");
}
//cron举例:(秒 - 分 - 时 - 日 - 月- 星期)
// */5 * * * * ? 每隔5秒执行一次
// 0 */1 * * * ? 每隔1分钟执行一次
// 0 0 1 * * ? 每天1点执行一次
// 0 0 1 1 * ? 每月1号1点执行一次
// 0 0 1 L * ? 每月最后一天1点执行一次
// 0 0 1 ? * L 每周星期天1点执行一次
}
上面使用@EnableScheduling的方式启动定时任务,等价于在spring xml中配置元素。
5. 开源任务调度框架Quartz
Quartz , 功能强大的任务调度库。适用于具有更复杂调度要求的场景。
提供了对持久化任务调度信息、事务、分布式的支持。与spring无缝对接。
6. 小结
使用ScheduledThreadPoolExecutor完成简单定时任务,是比较理想和常用的实现方式。书写时更容易理解其过程实现。
也可以用@Sheduled注解的形式,更加轻量化,看起来更简洁。
对复杂的任务调度,可以使用Quartz框架。
java实现周期任务_java定时任务的实现方式相关推荐
- java文件定时读写_java定时任务及日志的使用
需要引入日志的两个架包: log4j.jar和commons-logging.jar package com.lzl; import java.util.TimerTask; import org.a ...
- java的rsa作用_java 中RSA的方式实现非对称加密的实例
java 中rsa的方式实现非对称加密的实例 rsa通俗理解: 你只要去想:既然是加密,那肯定是不希望别人知道我的消息,所以只有我才能解密,所以可得出公钥负责加密,私钥负责解密:同理,既然是签名,那肯 ...
- java两二叉树相同_java – 最有效的方式来测试两个二叉树的相等性
您将如何在Java中实现二叉树节点类和二叉树类以支持最有效(从运行时角度)相等的检查方法(也必须实现): boolean equal(Node root1, Node root2) {} 要么 boo ...
- java反射效率对比_Java反射三种方式的效率对比
1 使用field long start = System.nanoTime(); Field[] fields = CallCount.class.getDeclaredFields(); for ...
- JAVA解决生产消费者_Java常用三种方式解决生产者消费者问题(详细)
package test; /** * Synchronized 版本解决生产者消费者 * wait() / notify()方法 */ import java.util.LinkedList; im ...
- java 向上抛异常_Java 异常的处理方式throws
在昨天的文章<Java 异常的分类与处理>中我们简单地了解了一下在方法声明的位置上使用throws关键字向上抛出异常,下面深入讲解异常的第一种处理方式throws. 下面深入讲解异常的第一 ...
- java数据加密解密代码_java使用RSA加密方式实现数据加密解密的代码
RSA的应用 RSA是一种非对称加密算法.现在,很多登陆表单的密码的都采用RSA加密,例如京东中的登陆使用公钥对密码进行加密 java使用RSA加密方式实现数据加密解密,需要首先产生私钥和公钥 测试代 ...
- java http请求实现_JAVA实现HTTP请求方式
get请求 public String sendGet(String httpurl) throws IOException { URL url = new URL(httpurl); HttpURL ...
- java ftp传图片_Java 图片上传方式一 : ftp 图片服务器
一 : Linux ftp 图片服务器 1. Linux 安装 ftp linux服务器配置 安装ftp yum install vsftpd 启动服务 service vsftpd start 开机 ...
最新文章
- 看初中生如何高薪就业
- python - 栈与队列(只有代码)
- MySQL 4.1/5.0/5.1/5.5各版本的主要区别
- 报错解决方法1:‘A GDAL API version must be specified.’
- Linux-diff和diff3命令
- centos7下安装低版本mysql_centos7下使用yum安装制定版本mysql
- winform直接控制云台_速学指南,2分钟学会Feiyu pocket口袋云台的隐藏功能操作
- 从Java到Go面向对象--继承思想.md
- linq to entity 左联接 右连接 以及内连接写法的区别(转)
- premnmx tramnmx postmnmx 函数用法
- 微软Power Platform在中国市场正式商用 无缝衔接微软智能云“三驾马车”
- 4个基本不等式的公式高中_基本不等式公式四个
- 微软文件共享服务器进程,Windows Server“8”– 将服务器应用程序存储转移到 Windows 文件共享...
- 随笔--初到青岛,爱意油然而生
- SCI三区论文大修笔记(已录用)
- 将数字编号翻译为英文编号(python)实现
- 2022最新MN梦奈宝塔主机系统V1.5版本+UI不错
- 不在乎 -- 陆琪
- 过滤器以及Severlet 的实例
- Taro小程序,底部输入框获取键盘高度动态设置bottom有延迟解决
热门文章
- Matlab矩阵查找
- 6个步骤卸载wine
- linux如何获取raw中的文件路径,如何使用Linux获取Touchscreen Rawdata的坐标
- mysql自增id用完了_MySQL表自增id用完了该怎么办?
- 【APICloud系列|38】 微信登录分享、QQ登录分享实现方法
- 早上起来CSDN的PC端主页积分变成了0
- mysql、oracle知识点总结
- mysql 更改root密码字段不存在_初次登陆MySQL修改密码是出现Unknown column 'password' in 'field list'的解决方法...
- 为自己写程序之JavsScript代码段测试器
- CSS揭秘(二)背景与边框