文档章节

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
JavaLib-quartz | 基于Spring Boot Quartz开发的定时任务

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

冯文议
07/30
0
0
【开源访谈】JTimer:crontab 的替代品,工程师的福音

作为程序员,在日常工作中免不了与各种任务打交道,有一些任务的执行是具有重复性质的,比如工作人员每天登录系统之后进行一系列基础操作:(1)先确认一下系统时间,(2)查看之前登录的用户...

h4cd
06/26
0
10
Spring Boot:在Spring Boot中使用定时任务

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

Element0506
2015/11/10
0
0
定时器 Quartz Java

1、几种任务调度的 Java 实现方法与比较 http://www.oschina.net/question/129540_28053 //特此感谢这篇文章的作者,我很喜欢这篇文章,里边介绍了好多关于目前定时器在工程中的使用,我总结...

soul_mate
2014/06/13
0
2

没有更多内容

加载失败,请刷新页面

加载更多

下一页

InvalidKeyException: Illegal key size

Caused by: java.lang.RuntimeException: java.security.InvalidKeyException: Illegal key size 解决方案:去官方下载JCE无限制权限策略文件。 jdk 5: http://www.oracle.com/technetwork/j......

自由的开源
16分钟前
0
0
JAVA秒杀实现以及优化原理

秒杀与其他业务最大的区别在于:秒杀的瞬间, (1)系统的并发量会非常的大 (2)并发量大的同时,网络的流量也会瞬间变大。 关于(2),最常用的办法就是做页面静态化,也就是常说的前后端分...

小贱是个程序员
20分钟前
1
0
Spring Aop之Advisor解析

在上文Spring Aop之Target Source详解中,我们讲解了Spring是如何通过封装Target Source来达到对最终获取的目标bean进行封装的目的。其中我们讲解到,Spring Aop对目标bean进行代理是通过Ann...

爱宝贝丶
22分钟前
0
0
Java高级工程师面试阿里,阿里云,天猫,菜鸟,涉及到的知识点

前言: 分享 Java高级工程师面试阿里,阿里云,天猫,菜鸟,涉及到的知识点,文章有点长,但比较全面,阅读时间15分钟左右,干货满满。 一、HashMap的那些事 1.1、HashMap的实现原理 1.1.1、...

Java大蜗牛
47分钟前
2
0
nginx模块学习五 expires 浏览器缓存

缓存原理 语法 Syntax: expires [modified] time;expires epoch | max | off;Default: expires off;Context: http,server,location,if in location 例/etc/nginx/conf.d/default.con......

Romanceling
58分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部