Java Web应用启动后执行定时任务-ScheduledThreadPoolExecutor

package com.XXXXX;

import java.util.Timer;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
 * @Description: TODO
 */
public class StartupListener4analysisReport implements ServletContextListener {
 @Override
 public void contextDestroyed(ServletContextEvent sce) {
  sce.getServletContext().log("定时器销毁");
 }
 @Override
 public void contextInitialized(ServletContextEvent sce) {
  sce.getServletContext().log("启动线程池");
  //让线程池去跑另外一个任务,,,此处暂不需要,注掉
 //  Start a thread pool to deal with different task;
 // PoolManager.pool = Executors.newFixedThreadPool(10);
  
  
  sce.getServletContext().log("启动定时器");
//  //Create a Daemon timer thread
//  Timer timer=new Timer(true);
//  // 每隔10秒钟执行任务
//  timer.schedule(new MyTimerTask(sce.getServletContext()), 0,10 * 1000);
//  sce.getServletContext().log("已经添加任务调度表");
  
  //自JDK5之后,可以用ScheduledThreadPoolExecutor来替代Timer。
        //构造一个ScheduledThreadPoolExecutor对象,并且设置它的容量为5个
  ScheduledThreadPoolExecutor stpe = new ScheduledThreadPoolExecutor(5);
  MyTimerTask4analysisReport myTimerTask4analysisReport = new MyTimerTask4analysisReport(sce.getServletContext());
  //scheduleAtFixedRate:隔60秒后开始执行任务,并且在固定间隔300秒再执行一次,循环下去;注意和scheduleWithFixedDelay区别开来
//  stpe.scheduleWithFixedDelay(myTimerTask4analysisReport, 10, 5, TimeUnit.SECONDS);
  stpe.scheduleAtFixedRate(myTimerTask4analysisReport, 60, 300, TimeUnit.SECONDS);


 }

}

 

 

以下是scheduleAtFixedRate 和scheduleWithFixedDealy的区别

 scheduleWithFixedDelay从字面意义上可以理解为就是以固定延迟(时间)来执行线程任务,它实际上是不管线程任务的执行时间的,每次都要把任务执行完成后再延迟固定时间后再执行下一次。而scheduleFixedRate呢,是以固定频率来执行线程任务,固定频率的含义就是可能设定的固定时间不足以完成线程任务,但是它不管,达到设定的延迟时间了就要执行下一次了。

1、scheduleAtFixedRate 方法,顾名思义,它的方法名称的意思是:已固定的频率来执行某项计划(任务)。

2、scheduleWithFixedDealy,相对固定的延迟后,执行某项计划。

单从它们的字面来看,还是让人困惑,跟TC的管猿似的,文字游戏。

还是比较简单明了的描述比较好:第一个方法是固定的频率来执行某项计划,它不受计划执行时间的影响。到时间,它就执行。

而第二个方法,相对固定,据鄙人理解,是相对任务的。即无论某个任务执行多长时间,等执行完了,我再延迟指定的时间。也就是第二个方法,它受计划执行时间的影响。

 

 

 

 

 

/**
 *
 */
package com.XXXX;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimerTask;

import javax.servlet.ServletContext;


/**
 * @Description: TODO
 */
public class MyTimerTask4analysisReport extends TimerTask {
 private ServletContext context = null;
//  private int  param;
    public MyTimerTask4analysisReport(ServletContext context) {
     this.context = context;
    }
 @Override
 public void run() {
  SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  context.log(format.format(new Date()) + "执行指定定時任务开始---下载分析报告");
  // 此处开始执行下载分析报告的任务。。。。。
  System.out.println("aaaaaaaaaaaaaaaaaaaaaaaaaa");
 //  让线程池去跑另外一个任务,,,此处暂不需要,注掉 
 // System.err.println("每30秒钟跑一次!要调用线程池去执行另外的任务");
 // PoolManager.pool.execute(new WorkThread(param++));
  
  context.log(format.format(new Date()) + "指定定時任务执行结束---下载分析报告");
 }
}

 

 

 

/**
 *
 */
package com.XXXX;

import java.util.concurrent.ExecutorService;

/**
 * @Description: TODO
 */
public class PoolManager {
 public static ExecutorService pool;
}

 

/**
 *
 */
package com.XXXX;
/**
 * @Description: TODO
 * Copyright (C), 1996-2011.
 */
public class WorkThread implements Runnable {
 private int param;
 public WorkThread(int param) {
  this.param = param;
 }
 @Override
 public void run() {
  // TODO Do something
  System.err.println("我被线程池调用执行啦~!参数:" + param);
 }

}

web.xml


 
  com.XXXXXX.StartupListener4analysisReport
 

 

你可能感兴趣的:(Java,Java多线程,JavaEE)