文档章节

java定时任务

t
 tragedyhome
发布于 2015/04/28 17:47
字数 1173
阅读 40
收藏 3
点赞 1
评论 0

全文检索系统需要定时建立索引,故需要定时执行某些任务,以下是实现思路:

单次任务使用timer.schedule(new task(),Date date)实现。

每天任务与每周任务使用timer.scheduleAtFixedRate(new task(),delay,period)实现,周期分别为24*1000/7*24*1000。

每月任务同每天任务,但周期不确定,思虑良久,采用java反射机制动态修改周期。

代码如下:

1、创建ServletContextListener类

package org.fulltext.task;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
/**
 * Application Lifecycle Listener implementation class TaskListener
 *
 */
@WebListener
public class TaskListener implements ServletContextListener {
    /**
     * Default constructor. 
     */
    public TaskListener() {
        // TODO Auto-generated constructor stub
    }
 /**
     * @see ServletContextListener#contextDestroyed(ServletContextEvent)
     */
    public void contextDestroyed(ServletContextEvent arg0)  { 
         // TODO Auto-generated method stub
     TaskManager.destoryTimer();
     
     
    }
 /**
     * @see ServletContextListener#contextInitialized(ServletContextEvent)
     */
    public void contextInitialized(ServletContextEvent arg0)  { 
         // TODO Auto-generated method stub
     TaskManager taskManager=new TaskManager();
    }
 
}

2、修改web.xml文件,在web-app下添加时间侦听。

  <listener>

   <listener-class>

     org.fulltext.task.TaskListener

   </listener-class>

  </listener>

3、创建taskManager类,该类通过timer执行定时任务,是定时任务的核心。

package org.fulltext.task;
public class TaskManager {
 
 static Logger logger=Logger.getLogger("logfile");
 public static List<Timer> timers=new ArrayList<Timer>();
 public TaskManager(){ 
  List<Taskconfig> taskconfigs=new ArrayList<Taskconfig>();
  TaskconfigDAO taskconfigDAO=new TaskconfigDAO();
  taskconfigs=taskconfigDAO.findAll();
  SimpleDateFormat simpleDateFormat;
  for (int i = 0; i <taskconfigs.size(); i++) {
   timers.add(i,new Timer("Tasktimer"+i,true));
  }
  for (int i = 0; i < taskconfigs.size(); i++) {
   if(taskconfigs.get(i).getTaskstate().trim().equals("0")||taskconfigs.get(i).getTaskstate().trim().equals("3")){
   }
   else{
    switch (taskconfigs.get(i).getTaskperiod().trim()) {
    case "once":
     
     if (taskconfigs.get(i).getTaskexcetime().before(new Date())) {
      simpleDateFormat=new SimpleDateFormat("HH:mm:ss");
      logger.warn("单次任务调度失败,原因:执行时间小于当前时间,"+"任务名:"+taskconfigs.get(i).getTaskname()+",任务所属"+taskconfigs.get(i).getTasktype()+",任务操作:"
        +taskconfigs.get(i).getTaskoperate()+" ,任务周期:"+taskconfigs.get(i).getTaskperiod()+",任务执行时间:"+simpleDateFormat.format(taskconfigs.get(i).getTaskexcetime()).toString());
      taskconfigs.get(i).setTaskstate("3");
      taskconfigDAO.save(taskconfigs.get(i));
     }
     else{
      simpleDateFormat=new SimpleDateFormat("HH:mm:ss");
      logger.info("单次任务调度成功,任务名:"+taskconfigs.get(i).getTaskname()+",任务所属"+taskconfigs.get(i).getTasktype()+",任务操作:"
        +taskconfigs.get(i).getTaskoperate()+" ,任务周期:"+taskconfigs.get(i).getTaskperiod()+",任务执行时间:"+simpleDateFormat.format(taskconfigs.get(i).getTaskexcetime()).toString());
      if ("recreate_index".equals(taskconfigs.get(i).getTaskoperate().trim())) {
       timers.get(i).schedule(new RecreateIndexTask(taskconfigs.get(i)), taskconfigs.get(i).getTaskexcetime());
      }else {
       timers.get(i).schedule(new CrawlIndexTask(taskconfigs.get(i)), taskconfigs.get(i).getTaskexcetime());
      }
     }
     break;
    case "day":
     long PERIOD_DAY = 24*60*60*1000;
     Calendar now=Calendar.getInstance();
     Calendar excetimeCalendar=Calendar.getInstance();
     excetimeCalendar.setTime(taskconfigs.get(i).getTaskexcetime());
     now.set(Calendar.HOUR_OF_DAY, excetimeCalendar.get(Calendar.HOUR_OF_DAY));
     now.set(Calendar.MINUTE, excetimeCalendar.get(Calendar.MINUTE));
     now.set(Calendar.SECOND, excetimeCalendar.get(Calendar.SECOND));
     Date excDate=now.getTime();
     while(excDate.before(new Date())){
      now.add(Calendar.DAY_OF_MONTH, 1);
      excDate=now.getTime();
     }
     simpleDateFormat=new SimpleDateFormat("HH:mm:ss");
     logger.info("每天任务调度成功,任务名:"+taskconfigs.get(i).getTaskname()+",任务所属"+taskconfigs.get(i).getTasktype()+",任务操作:"
       +taskconfigs.get(i).getTaskoperate()+" ,任务周期:"+taskconfigs.get(i).getTaskperiod()+",任务执行时间:"+simpleDateFormat.format(taskconfigs.get(i).getTaskexcetime()).toString());
     if ("recreate_index".equals(taskconfigs.get(i).getTaskoperate().trim())) {
      timers.get(i).scheduleAtFixedRate(new RecreateIndexTask(taskconfigs.get(i)), excDate,PERIOD_DAY);
      }else {
      timers.get(i).scheduleAtFixedRate(new CrawlIndexTask(taskconfigs.get(i)),excDate,PERIOD_DAY);
      }
     break;
    case "week":
     long PERIOD_WEEK = 7*24*60*60*1000;
     Calendar week_now=Calendar.getInstance();
     Calendar excetimeweek=Calendar.getInstance();
     excetimeweek.setTime(taskconfigs.get(i).getTaskexcetime());
     week_now.set(Calendar.DAY_OF_WEEK, new Integer(taskconfigs.get(i).getTaskweekday().trim()));
     week_now.set(Calendar.HOUR_OF_DAY, excetimeweek.get(Calendar.HOUR_OF_DAY));
     week_now.set(Calendar.MINUTE, excetimeweek.get(Calendar.MINUTE));
     week_now.set(Calendar.SECOND, excetimeweek.get(Calendar.SECOND));
     Date wexcDate=week_now.getTime();
     System.out.println(wexcDate+"===="+new Date());
     while(wexcDate.before(new Date())){
      week_now.add(Calendar.DAY_OF_MONTH, 7);
      wexcDate=week_now.getTime();
     }
     simpleDateFormat=new SimpleDateFormat("HH:mm:ss");
     logger.info("每周任务调度成功,任务名:"+taskconfigs.get(i).getTaskname()+",任务所属"+taskconfigs.get(i).getTasktype()+",任务操作:"
       +taskconfigs.get(i).getTaskoperate()+" ,任务周期:"+taskconfigs.get(i).getTaskperiod()+",任务执行时间:"+simpleDateFormat.format(taskconfigs.get(i).getTaskexcetime()).toString());
     if ("recreate_index".equals(taskconfigs.get(i).getTaskoperate().trim())) {
      System.out.println(wexcDate);
      timers.get(i).scheduleAtFixedRate(new RecreateIndexTask(taskconfigs.get(i)), wexcDate,PERIOD_WEEK);
      }else {
      timers.get(i).scheduleAtFixedRate(new CrawlIndexTask(taskconfigs.get(i)),wexcDate,PERIOD_WEEK);
      }
 
     break;
    case "month":
     Calendar month_now=Calendar.getInstance();
     Calendar excetime_month=Calendar.getInstance();
     excetime_month.setTime(taskconfigs.get(i).getTaskexcetime());
     while (month_now.getActualMaximum(Calendar.DAY_OF_MONTH)<new Integer(taskconfigs.get(i).getTaskmonday().trim())) {
      logger.warn("调度每月任务,因当前月份:"+(month_now.get(Calendar.MONTH)+1)+"月没有"+taskconfigs.get(i).getTaskmonday().trim()+"号,最大天数为:"+month_now.getActualMaximum(Calendar.DAY_OF_MONTH)+"故延后一月");
      month_now.add(Calendar.MONTH, 1);
     }
     month_now.set(Calendar.DAY_OF_MONTH, new Integer(taskconfigs.get(i).getTaskmonday().trim()));
     month_now.set(Calendar.HOUR_OF_DAY, excetime_month.get(Calendar.HOUR_OF_DAY));
     month_now.set(Calendar.MINUTE, excetime_month.get(Calendar.MINUTE));
     month_now.set(Calendar.SECOND, excetime_month.get(Calendar.SECOND));
     Date monthDate=month_now.getTime();
     while(monthDate.before(new Date())){
      month_now.add(Calendar.MONTH, 1);
      monthDate=month_now.getTime();
     }
     long PERIOD_month = month_now.getActualMaximum(Calendar.DAY_OF_MONTH)*24*60*60*1000L;
     simpleDateFormat=new SimpleDateFormat("HH:mm:ss");
     logger.info("每月任务调度成功,任务名:"+taskconfigs.get(i).getTaskname()+",任务所属"+taskconfigs.get(i).getTasktype()+",任务操作:"
       +taskconfigs.get(i).getTaskoperate()+" ,任务周期:"+taskconfigs.get(i).getTaskperiod()+",任务执行时间:"+simpleDateFormat.format(taskconfigs.get(i).getTaskexcetime()).toString());
     if ("recreate_index".equals(taskconfigs.get(i).getTaskoperate().trim())) {
       timers.get(i).scheduleAtFixedRate(new ReIndexOfMonth(taskconfigs.get(i)), monthDate,PERIOD_month);
      
      }else {
       timers.get(i).scheduleAtFixedRate(new CrawlIndexOfMonth(taskconfigs.get(i)), monthDate,PERIOD_month);
      }
     break;
    default:
     break;
    }
   }
  }
  HibernateSessionFactory.closeSession();
 }
 
 public static void destoryTimer() {
  for(int i=0;i<timers.size();i++){
   timers.get(i).cancel();
   timers.get(i).purge();
  }
  Map<Thread,StackTraceElement[]> threadmMap=Thread.getAllStackTraces();
     Set<Thread> keyThreads=threadmMap.keySet();      
     for (Iterator<Thread> it = keyThreads.iterator(); it.hasNext();) {           
      Thread thread=it.next();   
       if(thread.getName().indexOf("Tasktimer")>=0)
       thread.interrupt();
      }
  timers.clear();
  System.gc();
 }
}

4、最后创建timerTask类,该类包含run方法,run方法中放置需要执行的任务代码。

package org.fulltext.task;

import java.lang.reflect.Field;

import java.util.TimerTask;

import org.apache.commons.collections.map.StaticBucketMap;

public class ExecuteTask extends TimerTask{
 public void run() {
  // TODO Auto-generated method stub
  System.out.println("运行计划任务");
  setDeclaredField(TimerTask.class, this, "period", 1000);
 }
}

5、每月任务周期不固定,使用java反射机制动态修改执行周期字段。

package org.fulltext.task;
import java.lang.reflect.Field;
import java.util.TimerTask;
import org.apache.commons.collections.map.StaticBucketMap;
public class ExecuteTask extends TimerTask{
 static int p=0;
    static boolean setDeclaredField(Class<?> clazz, Object obj,  
        String name, int value) {  
     p=p+value;
        try {  
            Field field = clazz.getDeclaredField(name);  
            field.setAccessible(true);  
            field.set(obj, p);  
            return true;  
        } catch (Exception ex) {  
            ex.printStackTrace();  
            return false;  
        }  
    }
 @Override
 public void run() {
  // TODO Auto-generated method stub
  System.out.println("测试java反射机制");
  setDeclaredField(TimerTask.class, this, "period", 1000);
 }
}

编写timer时,需要释放资源,否则系统重启或重新加载任务会继续调度执行。 在ServletContextListener的contextDestroyed方法中添加删除timer取消及删除功能。

© 著作权归作者所有

共有 人打赏支持
t
粉丝 2
博文 3
码字总数 4069
作品 0
成都
sharding-jdbc源码分析—准备工作

原文作者:阿飞Javaer 原文链接:https://www.jianshu.com/p/7831817c1da8 接下来对sharding-jdbc源码的分析基于tag为源码,根据sharding-jdbc Features深入学习sharding-jdbc的几个主要特性...

飞哥-Javaer ⋅ 05/03 ⋅ 0

Android中实现定时器的四种方式

Android中实现定时器的四种方式 第一种方式利用Timer和TimerTask 1、继承关系 java.util.Timer 基本方法 schedule 例如: [java] view plaincopyprint? schedule方法有三个参数 第一个参数就...

Yao--靠自己 ⋅ 05/16 ⋅ 0

【Canal源码分析】Canal Instance启动和停止

一、序列图 1.1 启动 1.2 停止 二、源码分析 2.1 启动 这部分代码其实在ServerRunningMonitor的start()方法中。针对不同的destination,启动不同的CanalInstance。主要的方法在于initRunning...

端木轩 ⋅ 05/24 ⋅ 0

在Spring Boot中使用@Scheduled实现定时任务

在Spring Boot中使用@Scheduled实现定时任务 之前没有使用Spring Boot的Java风格配置的时候,用XML配置过@Scheduled定时任务,现在都习惯使用Java风格配置了,在此简单记录 一下Spring Boot...

Canaan_ ⋅ 05/11 ⋅ 0

SpringBoot整合Quartz定时任务

(1)什么是Quartz? (2)Quartz的特点; (3)Quartz专用词汇说明; (4)Quartz任务调度基本实现原理; 接下来看下具体的内容: (1)什么是Quartz? Quartz是一个完全由Java编写的开源作业...

weixin_38655836 ⋅ 04/11 ⋅ 0

君君要上天/JTimer for JAVA

JTimer for JAVA 项目介绍 基于SpringBoot+layui秒级定时任务管理,取代crontab PHP版本 https://gitee.com/itzhoujun/JTimer 项目预览 预览图请点击上方php版本连接,两个版本功能基本一致 ...

君君要上天 ⋅ 05/27 ⋅ 0

Java 工具集 Hutool 4.0.12 发布,紧急 bug 修复

Hutoo l是一个 Java 工具包,也只是一个工具包,它帮助我们简化每一行代码,减少每一个方法,让 Java 语言也可以“甜甜的”。Hutool 最初是我项目中“util”包的一个整理,后来慢慢积累并加入...

路小磊 ⋅ 05/10 ⋅ 6

Java:大数据技术领域的一匹黑马

诞生于1991年的Java如今已经成为世界范围内应用最为广泛的编程语言之一。在今天的文章中,我们将共同了解Java所拥有的七大关键新特性,展望其如何在未来的超级计算、大数据以及物联网等领域继...

Java大数据处理 ⋅ 04/22 ⋅ 0

注册中心 Eureka 源码解析 —— 应用实例注册发现(六)之全量获取

摘要: 原创出处 http://www.iocoder.cn/Eureka/instance-registry-fetch-all/ 「芋道源码」欢迎转载,保留摘要,谢谢! 本文主要基于 Eureka 1.8.X 版本 1. 概述 2. Eureka-Client 发起全量获...

芋道源码 ⋅ 06/02 ⋅ 0

甲骨文宣布新的 Java SE 订阅模式,为企业提供更广泛支持

甲骨文公司已经改进了Java SE(标准版)的商业支持计划,由之前企业一次性支付永久许可费用加年度支持费用的模式,改为新的订阅模式,并宣布新的模式将于2018年7月开始启用。个人使用和非商业...

达尔文 ⋅ 昨天 ⋅ 1

没有更多内容

加载失败,请刷新页面

加载更多

下一页

从方法论到零售客户实践 解码阿里巴巴数据中台——2018上海云栖大会

摘要: 一、数据中台之道 6月8日,上海云栖大会进入了第二天的议程,数据中台专场论坛座无虚席,数据中台总架构师邓中华女士向在场的观众介绍了数据中台的衍生发展之道。 基于OneID、OneData...

阿里云云栖社区 ⋅ 21分钟前 ⋅ 0

Ubuntu部署django问题汇总

使用Anaconda3的Python3.6的pip安装UWSGI报错 原因是gcc版本不兼容,安装4.7并修改gccsudo apt-get install gcc-4.7sudo mv /usr/bin/gcc /usr/bin/gcc.baksudo ln -s /usr/bin/gcc-4.......

wuyaSama ⋅ 24分钟前 ⋅ 0

从方法论到零售客户实践 解码阿里巴巴数据中台——2018上海云栖大会

摘要: 一、数据中台之道 6月8日,上海云栖大会进入了第二天的议程,数据中台专场论坛座无虚席,数据中台总架构师邓中华女士向在场的观众介绍了数据中台的衍生发展之道。 基于OneID、OneData...

猫耳m ⋅ 24分钟前 ⋅ 0

Docker减肥小记

如果经常使用 docker,你会发现 docker 占用的资源膨胀很快,其中最明显也最容易被察 如何快速的清理 docker 占用的系统资源,具体点说就是删除那些无用的镜像、容器、网络和数据卷… 1、查看...

寰宇01 ⋅ 35分钟前 ⋅ 0

微信小程序中如何使用WebSocket实现长连接(含完整源码)

本文由腾讯云技术团队原创,感谢作者的分享。 1、前言 微信小程序提供了一套在微信上运行小程序的解决方案,有比较完整的框架、组件以及 API,在这个平台上面的想象空间很大。腾讯云研究了一...

JackJiang- ⋅ 43分钟前 ⋅ 0

定制库到Maven本地资源库

1.如果只有定制库的JAR文件 下载链接如下:pdf.jar 2.使用命令转换成Maven本地资源 mvn install:install-file -Dfile=/Users/manager/Downloads/clj-pdf-2.2.33.jar -DgroupId=clj-pdf -Dar......

年少爱追梦 ⋅ 47分钟前 ⋅ 0

高仿springmvc之xuchen-mvc

package org.mvc.framework.servlet; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.......

徐志 ⋅ 49分钟前 ⋅ 0

关于自定义URLStreamHandler的一次踩坑

关于自定义URLStreamHandler的一次踩坑 20180625 lambo init 说明 一般自定义实现url的协议解析.方案为实现URLStreamHandler.实现其 openConnection 就可以了, 如果我们执行 new URL("xx://...

林小宝 ⋅ 50分钟前 ⋅ 0

【SM2证书】利用BC的X509v3CertificateBuilder组装X509国密证书

演示证书文件 链接: https://pan.baidu.com/s/1ijHNnMQJj7jzW-jXEVd6Gg 密码: vfva 所需jar包 <!-- https://mvnrepository.com/artifact/org.bouncycastle/bcpkix-jdk15on --> <dependenc......

小帅帅丶 ⋅ 51分钟前 ⋅ 0

用Calendar 实现 计算 一段时间的毫秒值

Calendar c=Calendar.getInstance();c.add(Calendar.MONTH, -1);int lastMonthMaxDay=c.getActualMaximum(Calendar.DAY_OF_MONTH);c.set(c.get(Calendar.YEAR), c.get(Calendar.MONTH)......

岸芷汀兰 ⋅ 55分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部