java用ScheduledThreadPoolExecutor实现定时任务

java | 2019-09-13 10:02:39

java用ScheduledThreadPoolExecutor实现定时任务比Timer稳定


1.ScheduledThreadPoolExecutor简介
java开始提供ScheduledThreadPoolExecutor类来支持周期性任务的调度,在这之前,这些工作需要依靠TimerTimerTask或者其它第三方工具来完成。但Timer有着不少缺陷,如Timer是单线程模式,调度多个周期性任务时,如果某个任务耗时较久就会影响其它任务的调度;如果某个任务出现异常而没有被catch则可能导致唯一的线程死掉而所有任务都不会再被调度。ScheduledThreadPoolExecutor解决了很多Timer存在的缺陷。

2.ScheduledThreadPoolExecutor和Timer比较
Timer对调度的支持是基于绝对时间的,因此任务对系统时间的改变是敏感的;而ScheduledThreadPoolExecutor支持相对时间。
·Timer使用单线程方式来执行所有的TimerTask,如果某个TimerTask很耗时则会影响到其他TimerTask的执行;而ScheduledThreadPoolExecutor则可以构造一个固定大小的线程池来执行任务。
·Timer不会捕获由TimerTask抛出的未检查异常,故当有异常抛出时,Timer会终止,导致未执行完的TimerTask不再执行,新的TimerTask也不能被调度;ScheduledThreadPoolExecutor对这个问题进行了妥善的处理,不会影响其他任务的执行。

3.ScheduledThreadPoolExecutor的主要方法:

3.1在指定的延迟后执行
<V>ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit)

3.2在指定的延迟后执行
ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit)

3.3在指定的延迟后以固定速率执行(类似Timer.scheduleAtFixedRate())
ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)

3.4在指定的延迟后以固定间隔执行(类似Timer.schedule())
ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)
        
4.ScheduledThreadPoolExecutor定时任务案例(随tomcat启动的定时收短信的案例)
        4.1.定时任务代码

/**
* 执行定时任务
* @author Administrator
*
*/
public class RepTaskScheduler implements Runnable{
        
        
        private static final SMSManage smsManage=new SMSManage();
        
        /**
         * 初始化定时器
         */
        public static void inist(){
                ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor(10);
                RepTaskScheduler initTiming = new RepTaskScheduler();
                scheduler.scheduleAtFixedRate(initTiming,10,10,TimeUnit.SECONDS);10秒后启动,没隔10秒启动一次。
        }
        
        /**
         * 这里写要定时执行的所有任务
         */
        @Override
        public void run() {
                //定时获取短信
                smsManage.getSMS();
        }
        
}



4.2.随tomcat启动的servlet代码
       

public class InitServlet extends InitServletBase implements ServletContextListener {
  public void init(ServletContext servletContext) throws ServletException {
    super.init(servletContext);
  }
  public void contextInitialized(ServletContextEvent arg0) {
    try {
      init(arg0.getServletContext());
      RepTaskScheduler.inist();
    } catch (ServletException e) {
      System.out.println("初始化出错!");
    }
  }
  public void contextDestroyed(ServletContextEvent arg0) {
          
  }
}



登录后即可回复 登录 | 注册
    
关注编程学问公众号