引自:http://www.cnblogs.com/wenbronk/p/6433178.html

java中的定时任务, 使用java实现有3种方式:

1, 使用普通thread实现

  @Test
public void test1() {
// 单位: 毫秒
final long timeInterval = 1000;
Runnable runnable = new Runnable() {
public void run() {
while (true) {
// ------- code for task to run
System.out.println("Hello !!");
// ------- ends here
try {
Thread.sleep(timeInterval);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Thread thread = new Thread(runnable);
thread.start();
}

2, 使用timer实现: 可控制启动或取消任务, 可指定第一次执行的延迟

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

@Test
public void test2 () {
TimerTask task = new TimerTask() {
@Override
public void run() {
System.out.println("Hello !!!");
}
};
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, 使用 ScheduledExcecutorService 实现

  ScheduledExecutorService 是java.util.concurrent种的额一个累, 用于实现定时任务

  它可以: 1, 通过线程池的方式执行任务

      2, 设定第一次的延迟事件

      3, 提供良好的约定, 设定时间间隔

@Test
public void test() {
Runnable runnable = new Runnable() {
public void run() {
System.out.println("Hello !!");
}
};
ScheduledExecutorService service = Executors
.newSingleThreadScheduledExecutor();
// 第二个参数为首次执行的延时时间,第三个参数为定时执行的间隔时间
service.scheduleAtFixedRate(runnable, 10, 1, TimeUnit.SECONDS);
}

4, 使用spring的 spring-task 实现

   第一种方式, 注解的方式实现

@Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Scheduled
{
public abstract String cron(); public abstract long fixedDelay(); public abstract long fixedRate();
}
fixedDelay: 设定间隔时间为 5000ms
fixedRate: 设定固定速率, 以固定速率5s来执行
cron="0 0 2 * * ? ": 使用时间表达式

   第二种方式, 配置文件配置的方式实现

 <task:scheduled-tasks>
<task:scheduled ref="taskJob" method="job1" cron="0 * * * * ?"/>
</task:scheduled-tasks>
/* taskJob 为执行任务类, job1 为执行的函数*/
<context:component-scan base-package="com.wenbronk.mytask " />

    2, 添加配置信息    

<!—开启这个配置,spring才能识别@Scheduled注解   -->
<task:annotation-driven scheduler="qbScheduler" mode="proxy"/>
<task:scheduler id="qbScheduler" pool-size="10"/>

    3, 代码实现 

@Scheduled(fixedDelay = 5000)
public void doSomething() {
// something that should execute periodically
}

时间表达式

一个cron表达式有至少6个(也可能7个)有空格分隔的时间元素。
按顺序依次为
秒(0~59)
分钟(0~59)
小时(0~23)
天(月)(0~31,但是你需要考虑你月的天数)
月(0~11)
天(星期)(1~7 1=SUN 或 SUN,MON,TUE,WED,THU,FRI,SAT)
年份(1970-2099)

常用的表达式为:

0 0 10,14,16 * * ? 每天上午10点,下午2点,4点
0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时
0 0 12 ? * WED 表示每个星期三中午12点
"0 0 12 * * ?" 每天中午12点触发
"0 15 10 ? * *" 每天上午10:15触发
"0 15 10 * * ?" 每天上午10:15触发
"0 15 10 * * ? *" 每天上午10:15触发
"0 15 10 * * ? 2005" 2005年的每天上午10:15触发
"0 * 14 * * ?" 在每天下午2点到下午2:59期间的每1分钟触发
"0 0/5 14 * * ?" 在每天下午2点到下午2:55期间的每5分钟触发
"0 0/5 14,18 * * ?" 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
"0 0-5 14 * * ?" 在每天下午2点到下午2:05期间的每1分钟触发
"0 10,44 14 ? 3 WED" 每年三月的星期三的下午2:10和2:44触发
"0 15 10 ? * MON-FRI" 周一至周五的上午10:15触发
"0 15 10 15 * ?" 每月15日上午10:15触发
"0 15 10 L * ?" 每月最后一日的上午10:15触发
"0 15 10 ? * 6L" 每月的最后一个星期五上午10:15触发
"0 15 10 ? * 6L 2002-2005" 2002年至2005年的每月的最后一个星期五上午10:15触发
"0 15 10 ? * 6#3" 每月的第三个星期五上午10:15触发

5, 使用 第三方插件 Quartz实现

 maven依赖

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

5. 1) 可以设置一个类, 继承自 QuartzJobBean

 1, 配置文件:

    <!-- 配置作业类 -->
<bean name="job1" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.gy.Job1" />
<property name="jobDataAsMap">
<map>
<entry key="timeout" value="0" />
</map>
</property>
</bean> <!-- 配置触发方式 -->
<!-- simpleTrggerBean 只支持一种方式调度 -->
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="job1" />
<property name="startDelay" value="0" />  <!-- 调度工厂实例化后,经过0秒开始执行调度 -->
<property name="repeatInterval" value="2000" />  <!-- 每2秒调度一次 -->
</bean> <!-- 使用CronTrggerBean , 支持时间表达式 -->
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="job1" />
<!-- 每天12点运行一次 -->
<property name="cronExpression" value="0 0 12 * * ?" />
</bean>

  2, 配置调度工厂:

    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="cronTrigger" />
</list>
</property>
</bean>

   3, 定义作业类:

public class Job1 extends QuartzJobBean {
private int timeout;
private static int i = 0;
// 调度工厂实例化后,经过timeout时间开始执行调度
public void setTimeout(int timeout) {
this.timeout = timeout;
}
/**
* 要调度的具体任务
*/
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
System.out.println("定时任务执行中…");
}
}

5.2) 直接写一个普通类, 在配置中进行配置

  任务类:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate; /**
* 定时删除用户收听过的poi
* @author wenbronk
* @time 2017年3月28日 下午2:01:09 2017
*/
public class DelListenerPOIScheduler { @Autowired
private StringRedisTemplate redisTemplate; public void doCheck() {
System.out.println("定时任务执行了....");
} }

配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd"> <!-- 配置作业类 -->
<bean id="delRedisListenerHistory" class="com.iwhere.easy.travel.valid.DelListenerPOIScheduler" /> <!-- 作业类描述, 使用方法调度 -->
<bean id="methodInvoking"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="delRedisListenerHistory" />
<property name="targetMethod" value="doCheck" />
</bean> <!-- 触发器, 使用定时触发 -->
<bean id="delTrigger"
class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="methodInvoking" />
<property name="cronExpression" value="0/10 * * * * ?" />
</bean> <!-- 总调度器 -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="delTrigger" />
</list>
</property>
</bean> </beans>

6, 在springboot中实现定时任务:

package com.iwhere.base.scheduling;

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled; /**
* 整合定时任务
* EnableScheduling 实现spring中的task功能
* @Scheduled中配置时间表达式
* @author 231
*
*/
@Configuration // 相当于配置beans,
@EnableScheduling // <task:*>, 让spring进行任务调度
public class SchedulingConfig { @Scheduled(cron="0/20 * * * * ?") // 20秒执行一次
public void scheduler() {
System.out.println("定时任务执行了");
} }

7, Springboot 集成 quartz

为什么非要集成呢, 因为quartz支持集群定时任务, 现在还用不到, 防止以后用到

1, 配置quartz的配置信息类

package com.iwhere.easy.travel.timeschedule;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
/**
* quartz的配置信息
* @author wenbronk
* @time 2017年3月29日 下午5:20:29 2017
*/
@Configuration
public class TimeScheduleConfig { @Bean(name = "detailFactoryBean")
public MethodInvokingJobDetailFactoryBean detailFactoryBean(DelListenerPOIScheduler scheduledTasks) {
MethodInvokingJobDetailFactoryBean bean = new MethodInvokingJobDetailFactoryBean();
// 这儿设置对应的Job对象
bean.setTargetObject(scheduledTasks);
// 这儿设置对应的方法名 与执行具体任务调度类中的方法名对应
bean.setTargetMethod("doCheck");
bean.setConcurrent(false);
return bean;
} @Bean(name = "cronTriggerBean")
public CronTriggerFactoryBean cronTriggerBean(MethodInvokingJobDetailFactoryBean detailFactoryBean) {
CronTriggerFactoryBean trigger = new CronTriggerFactoryBean();
trigger.setJobDetail(detailFactoryBean.getObject());
try {
trigger.setCronExpression("0 0 1 * * ?");// 每天1点执行一次
} catch (Exception e) {
e.printStackTrace();
}
return trigger; } @Bean
public SchedulerFactoryBean schedulerFactory(CronTriggerFactoryBean cronTriggerBean) {
SchedulerFactoryBean schedulerFactory = new SchedulerFactoryBean();
schedulerFactory.setTriggers(cronTriggerBean.getObject());
return schedulerFactory;
} }

2), 具体的作业类

package com.iwhere.easy.travel.timeschedule;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component; /**
* 定时删除用户收听过的poi
* @author wenbronk
* @time 2017年3月28日 下午2:01:09 2017
*/
@Component
@Configurable
@EnableScheduling
public class DelListenerPOIScheduler {
private Logger LOGGER = LoggerFactory.getLogger(DelListenerPOIScheduler.class); @Autowired
private StringRedisTemplate redisTemplate; public void doCheck() { try {
String key = "noteUserListenedPoi:*";
redisTemplate.delete(key);
LOGGER.info("redis中用户收听历史被清空");
} catch (Exception e) {
e.printStackTrace();
LOGGER.error("redis删除用户收听记录失败");
}
} }

系列原创, 转载请注明出处, 谢谢 @Wenbronk: http://www.cnblogs.com/wenbronk/p/6433178.html

转:java中的定时任务的更多相关文章

  1. Java 中的定时任务(一)

    定时任务简单来说就是在指定时间,指定的频率来执行一个方法,而在 Java 中我们又该如何实现呢? 想来主要有 3 种方式,最原始的方式肯定是开启一个线程,让它睡一会跑一次睡一会跑一次这也就达到了定频率 ...

  2. Java中的定时任务

    现代的应用程序早已不是以前的那些由简单的增删改查拼凑而成的程序了,高复杂性早已是标配,而任务的定时调度与执行也是对程序的基本要求了. 很多业务需求的实现都离不开定时任务,例如,每月一号,移动将清空你上 ...

  3. java中实现定时任务 task 或quartz

    转载大神的 https://www.cnblogs.com/hafiz/p/6159106.html https://www.cnblogs.com/luchangyou/p/6856725.html ...

  4. java中的定时任务小示例

    package package_1; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Timer; ...

  5. java中实现定时功能

    网上资料: 我们可以使用Timer和TimerTask类在java中实现定时任务,详细说明如下: 1.基础知识java.util.Timer一种线程设施,用于安排以后在后台线程中执行的任务.可安排任务 ...

  6. java中基于TaskEngine类封装实现定时任务

    主要包括如下几个类: 文章标题:java中基于TaskEngine类封装实现定时任务 文章地址: http://blog.csdn.net/5iasp/article/details/10950529 ...

  7. 在Java Web项目中添加定时任务

    在Java Web程序中加入定时任务,这里介绍两种方式:1.使用监听器注入:2.使用Spring注解@Scheduled注入. 推荐使用第二种形式. 一.使用监听器注入 ①:创建监听器类: impor ...

  8. 如何用 Java 实现 Web 应用中的定时任务?

    定时任务,是指定一个未来的时间范围执行一定任务的功能.在当前WEB应用中,多数应用都具备任务调度功能,针对不同的语音,不同的操作系统, 都有其自己的语法及解决方案,windows操作系统把它叫做任务计 ...

  9. 如何用 Java 实现 Web 应用中的定时任务

    定时任务,是指定一个未来的时间范围执行一定任务的功能.在当前WEB应用中,多数应用都具备任务调度功能,针对不同的语音,不同的操作系统, 都有其自己的语法及解决方案,windows操作系统把它叫做任务计 ...

随机推荐

  1. 小程序 - 图片列表显示lazyload效果

    在做一个短视频平台,涉及到的都是一些列表模块.因为小程序没有提供lazyload api,所以只能自己写一个了... 开发涉及 <scroll-view></scroll-view& ...

  2. 使用canvas及js简单生成验证码方法

    在很多时候都需要用到验证码,前端验证码需要知道Html5中的canvas知识点.验证码生成步骤是:1.生成一张画布canvas 2.生成随机数验证码  3.在画布中生成干扰线  4.把验证码文本填充到 ...

  3. 内存分配malloc函数注意事项。

    malloc的全称是memory allocation,中文叫动态内存分配,用于向系统申请分配指定字节的内存空间 原型:extern void *malloc(unsigned int num_byt ...

  4. Jmeter(一)http接口添加header和cookie --转载

    Jmeter(一)http接口添加header和cookie   HTTP信息头管理器在Jmeter的使用过程中起着很重要的作用,通常我们在通过Jmeter向服务器发送http请求(get或者post ...

  5. table是可语义化

    为了使我们的网站更好的被搜索引擎抓取收录,更自然的获得更高的流量,网站标签的语义化就显得尤为重要.所谓标签语义化,就是指标签的含义. 为了更好的理解标签的语义化,先看下面这个例子: <table ...

  6. Mantis中的状态

    在 Mantis中的 问题状态一共有以下几种 10:new,20:feedback,30:acknowledged,40:confirmed,50:assigned,80:resolved,90:cl ...

  7. dede如何调用一级栏目和子集栏目及其文章

    {dede:channelartlist row=6} <a href='{dede:field name='typeurl'/}'>{dede:field name='typename' ...

  8. Python3基本数据类型(一、数字类型)

    第一次写博客,感觉心情比较紧张,有一种要上台演讲的紧张感(虽然可能大概也许不会有人看).在此立个flag,以后每个学习阶段都要写一篇博客,来记录自己学习成长的这段日子.Fighting! 废话不多说, ...

  9. 「C基础」位运算

    0. 原码.补码.反码 初学者只做了解即可 见 张子秋的博客 无论正负数,在内存中存储的都是补码 正数:反码 == 原码 == 补码 负数:反码 == ~原码 补码 == 反码+1 1. & ...

  10. Windows 备用数据流(ADS)的妙用___转载

    NTFS交换数据流(Alternate Data Streams,简称ADS)是NTFS磁盘格式的一个特性,在NTFS文件系统下,每个文件都可以存在多个数据流.通俗的理解,就是其它文件可以“寄宿”在某 ...