文档章节

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
分布式定时任务框架---Uncode Schedule

分布式定时任务框架---Uncode Schedule rabbitGYK 关注 2016.11.27 20:36* 字数 1446 阅读 7141评论 5喜欢 36赞赏 1 博客原文 作为一个支付公司的项目组,经常会有很多对账功能(签约对账、支...

晨猫
11/02
0
0
justlive1/oxygen

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

justlive1
10/08
0
0
轻量级 Java 框架 - JOxygen

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

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

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

冯文议
07/30
0
0

没有更多内容

加载失败,请刷新页面

加载更多

深度学习中的注意力机制

最近两年,注意力模型(Attention Model)被广泛使用在自然语言处理、图像识别及语音识别等各种不同类型的深度学习任务中,是深度学习技术中最值得关注与深入了解的核心技术之一。 本文以机器...

火力全開
1分钟前
0
0
去除文件中

最近生成的文件中出现了<feff>乱码,而且单个文件中出现不止一次,在vim中打该文件显示<feff>,而在idea中则显示一个“-”,对数据处理造成了极大的困扰,通过使用其它编辑器打开发现,Windo...

休辞醉倒
3分钟前
0
0
想搞懂大数据就看这篇文章就够了!

互联网时代的到来,各种专业词汇术语充斥着我们的大脑,大数据,人工智能更是当下时代的热点潮流,很多传统企业都徘徊穿梭于这个潮流当中,传统广告的褪去,移动互联网时代的大数据精准整合营...

董黎明
5分钟前
1
0
go module 初体验

尽管官方的go module比较好用,但由于很多库下载不了,所以需要用到以下配置 export PATH=/mnt/d/download/go/bin/:$PATH export GOPATH=/home/fish/dipamkara/ #export GOPATH=/mnt/d/work...

LoveCupid
8分钟前
1
0
【小白学游戏常用算法】二、A*启发式搜索算法

  在上一篇博客中,我们一起学习了随机迷宫算法,在本篇博客中,我们将一起了解一下寻路算法中常用的A*算法。   通常情况下,迷宫寻路算法可以使用深度优先或者广度优先算法,但是由于效...

hejunbinlan
12分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部