文档章节

java定时任务

t
 tragedyhome
发布于 2015/04/28 17:47
字数 1173
阅读 40
收藏 3

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

单次任务使用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
博文 8
码字总数 4069
作品 0
成都
私信 提问
通过Shell脚本用JDBC连数据库脱离项目框架执行Java业务流程

一.概述 如果项目中需要使用到定时任务来完成某些业务,一般有两种做法:定时任务依赖于项目;定时任务用批处理(windows执行)或者shell脚本(Linux)启动,不依赖于项目。 个人觉得,定时任...

谢思华
2015/08/10
0
0
justlive1/oxygen

oxygen 轻量级Java框架 介绍 一个轻量级Java框架 oxygen-core 核心部分 基于cglib的aop实现 提供缓存管理和基于注解的缓存,内置LocalCache和Ehcache实现,可扩展 配置管理,支持${attrs.key...

justlive1
10/08
0
0
JavaLib-quartz | 基于Spring Boot Quartz开发的定时任务

基于Spring Boot Quartz开发的JavaLib-quartz,目的是帮你快速构建定时任务系统,你可以专心编写你的业务逻辑,而不必关注定时任务具体是如何实现的,他的性能如何,有没有异常以及异常处理,...

冯文议
07/30
0
0
SpringBoot | 第二十二章:定时任务的使用

前言 上两章节,我们简单的讲解了关于异步调用和异步请求相关知识点。这一章节,我们来讲讲开发过程也是经常会碰见的定时任务。比如每天定时清理无效数据、定时发送短信、定时发送邮件、支付...

oKong
08/19
0
2
Spring Boot:在Spring Boot中使用定时任务

本文主要介绍如何在Spring Boot中使用定时任务,假设你已经建好了一个基础的Spring Boot项目。首先,我们在项目中建立一个定时任务。 1.创建定时任务 package hello;import java.text.Simpl...

Element0506
2015/11/10
0
0

没有更多内容

加载失败,请刷新页面

加载更多

nuc970 uboot nand-boot,kernel, filesystem 烧录位置

一 烧写到Nand Flash **1.1 **相关文件说明 l BSP版本:nuc970bsp-release-20150519.zip l NuWriter版本:2015/04/28-V01,nuvoTon Nu-Writer V1.0 l 烧写文件: u-boot-spl.bin:负责将u-b......

CookieDemo
22分钟前
1
0
python中sort和sorted函数小结

L.sort(cmp=None, key=None, reverse=False) sorted(iterable, cmp=None, key=None, reverse=False) 这样看,sorted函数只比sort函数多一个iterable参数,其余没什么不同,iterable是一个迭代......

上官夏洛特
49分钟前
3
0
thinkphp 常用SQL执行语句总结

第一条:Db::tablera('vr_panomas')->where(['delete_time'=>0,'id'=>['in',$pids]])->field(['id'=>'id','post_thumb'=>'thumb','post_title'=>'title','post_tags'=>'tags','post_price'=>......

koothon
58分钟前
1
0
支付宝返回状态resultStatus意思

上一篇集成支付宝的时候,会有一些支付宝返回的resultStatus,具体意思是: 9000 订单支付成功 8000 正在处理中 4000 订单支付失败 6001 用户中途取消 6002 网络连接出错 还有memo,意思就是...

RainOrz
今天
2
0
electron webview 页面加载事件顺序

1.did-start-loading 页面开始加载 2.load-commit 主页面文档加载 3.page-title-updated title 4.dom-ready 主页面 dom 加载完成 5.load-commit frame文档加载 6.did-frame-finish-load fram......

dubox
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部