小弟写了个访问统计,里面有个web定时任务,实现了ServletContextListener接口,在web工程启动时自动加载该任务,然后每隔10分钟执行一次,判断是否到统计时间,若是,开始统计,不是退出!现在出现了一个问题:就是在window平台运行比较正常,在linux,aix中比较诡异,出现昨天能统计,今天不统计,然后过几天又统计的现象,请各位高手帮忙看看,不胜感激!
代码如下:
import java.util.Timer;import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;import com.hanweb.common.log.LogWriter;/**
 * 访问统计监听器 负责加载任务调度
 * 
 * @author yanghui
 * 
 */public class CountListener implements ServletContextListener {    private Timer timer = null;    // 监听器初始化,加载任务调度
    public void contextInitialized(ServletContextEvent e) {
        // LogWriter.setAppName("VisitCount");
        // LogWriter.setStyle(2);
        // LogWriter.setLevel(4);
        timer = new Timer(true);
        e.getServletContext().log("访问统计监听器开启启动...");
        LogWriter
                .debug("类:CountListener,方法:contextInitialized,信息:访问统计监听器开启启动...");
        // TimeSechedule()为任务作业
        timer.schedule(new TimeSechedule(), 0, 1000 * 10 * 60);
        e.getServletContext().log("启动完毕,并成功加载数据汇总任务调度");
        LogWriter
                .debug("类:CountListener,方法:contextInitialized,信息:启动完毕,并成功加载数据汇总任务调度");
    }    // 监听器销毁
    public void contextDestroyed(ServletContextEvent e) {
        timer.cancel();
        e.getServletContext().log("系统正被关闭!");
        LogWriter.debug("类:CountListener,方法:contextInitialized,信息:系统正被关闭!");
    }}import java.util.TimerTask;import com.hanweb.common.log.LogWriter;
import com.hanweb.common.util.IniFile;
import com.hanweb.dbmanager.Manager;
import com.hanweb.visitcount.util.ConfigPath;
import com.hanweb.visitcount.util.DataCountFunc;/**
 * 任务调度,执行数据汇总和报表生成
 * 
 * @author yangxi
 * 
 */
public final class TimeSechedule extends TimerTask {    // 任务调度的标志,true为正在运行
    public static boolean isRuning = false;    public void run() {
        // TODO Auto-generated method stub
        if (!isRuning) {
            // datacountFunc.getDate(int type,int d,int m)可以获得指定日期
            // type,1:年 2:月,3:日,4:时
            // d:获取指定的前N天值
            // m:获取指定的前N月值
//            System.out.println("----test-----"+(new Date()));
            //获取当前的系统时间:小时值,在下面有介绍
            int hour = DataCountFunc.getDate(4, 0, 0);
            String count_time = null;
            // 获取全局配置文件sys.ini,此文件规定了任务调度执行时间counttime
            String path = ConfigPath.getParaIniPath();
          //读取配置文件统计时间的信息,counttime为配置文件中统计时间的字段
            IniFile inifile = new IniFile(path);
            try {
                if (inifile.readIni()) {
                    count_time = inifile.getIniValue("counttime");
                    int i = Integer.parseInt(count_time);
                    if (inifile != null) {
                        inifile = null;
                    }
                    if ((hour == i) || (hour > i && hour <= 6)) {
                        isRuning = true;
                        //开始统计
                        startCount();
                        //删除冗余数据
                        deleteData();
                        // System.gc();
                    }
                }
            } catch (Exception e) {
                // LogWriter.debug("类:TimeSechedule,方法:run
                // ,信息:读取配置文件sys.ini失败!");
                LogWriter.debug("类:TimeSechedule,方法:run ,信息:发生错误," + e);
                if (inifile != null) {
                    inifile = null;
                }
                // 如果读取文件失败,则默认为2点统计
                if (hour >= 2 || hour <= 6) {
                    try {
                        isRuning = true;
                        startCount();
                        deleteData();
                    } catch (Exception e1) {
                        LogWriter.debug("类:TimeSechedule,方法:run ,发生错误," + e1);
                    } finally {
                        isRuning = false;
                    }
                    // System.gc();
                }
            } finally {
                isRuning = false;
            }
        } else {
            LogWriter.debug("类:TimeSechedule,方法:run ,信息:任务调度正在执行中!");
        }
    }    /**
     * 获得当前日期年,月,日,时
     * 
     * @param type
     *            1:Year,2:Month,3:Day
     * @return
     */
    public static int getDate(int type, int d, int m) {
        int result = 0;
        Calendar cal = Calendar.getInstance();
        if (d != 0) {
            cal.add(Calendar.DAY_OF_YEAR, -d);
        } else {
            if (m != 0) {
                cal.add(Calendar.MONTH, -m);
            }
        }
        switch (type) {
        case 1:
            result = cal.get(Calendar.YEAR);
            break;
        case 2:
            result = cal.get(Calendar.MONTH) + 1;
            break;
        case 3:
            result = cal.get(Calendar.DAY_OF_MONTH);
            break;
        case 4:
            result = cal.get(Calendar.HOUR_OF_DAY);
            break;
        }
        cal.clear();
        cal = null;
        return result;
    }

解决方案 »

  1.   

    我新来的,第一次留言,你可以试下用Quartz开源产品,如果用了spring的话,spring中也有作业调度配置,我们很多软件都是用spring的作业调度,没的问题.
      

  2.   

    自己发现了一个问题,当前一个任务还没有完成,后一个任务又开始执行,可是已经有标志isRunning来控制,可是为什么不起作用?
      

  3.   

    Quartz 是一个强大的企业级 Schedule 工具,也是目前最好的开源 Schedule 工具。Spring中也集成了quartz的应用
      

  4.   

    帮你找个参考代码吧
    http://www.javaeye.com/topic/117244
      

  5.   

    做定时的我们一般都还是有Quartz   的Time类不准确
      

  6.   

    Time类不准确  不提倡用于精确的定时任务
      

  7.   

    各位还能提供QQ或MSN,我想问下quartz的用法
      

  8.   

    quartz  的API文档上有的
      

  9.   

    javaeye里面也有不少参考的文章我以前就是对API做的
      

  10.   

    你进入if(!isRuning)就把这个标志设置成true最后在finally设置false