使用Timer和ScheduledThreadPoolExecutor执行定时任务

简介: 定时任务是在指定时间执行程序,或周期性执行计划任务。Java中实现定时任务的方法有很多,主要JDK自带的一些方法以及开源程序如Qurtz。

定时任务是在指定时间执行程序,或周期性执行计划任务。Java中实现定时任务的方法有很多,主要JDK自带的一些方法以及开源程序如Qurtz。

1.Timer和TimerTask

Timer只是充当了一个执行者的角色,真正的任务逻辑是通过一个叫做TimerTask的抽象类完成的,TimerTask也是java.util包下面的类,
它是一个实现了Runnable接口的抽象类,包含一个抽象方法run( )方法,需要我们自己去提供具体的业务实现。

Timer 的优点在于简单易用,但由于所有任务都是由同一个线程来调度,
因此所有任务都是串行执行的,同一时间只能有一个任务在执行,前一个任务的延迟或异常都将会影响到之后的任务。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public  class  TimerTest { 
     //被执行的任务必须继承TimerTask,并且实现run方法
     static  class  MyTimerTask1  extends  TimerTask { 
         public  void  run() { 
             System.out.println( "执行当前线程" +Thread.currentThread().getName()); 
        
     }    
     /**
      * Timer线程不会捕获异常,所以TimerTask抛出的未检查的异常会终止timer线程。
      * 如果Timer线程中存在多个计划任务,其中一个计划任务抛出未检查的异常,则会引起整个Timer线程结束,从而导致其他计划任务无法得到继续执行。  
      * Timer线程时基于绝对时间,因此计划任务对系统的时间的改变是敏感的。
      * Timer是单线程,如果某个任务很耗时,可能会影响其他计划任务的执行。
      * @param args
      * @throws ParseException
      * @throws InterruptedException
      */
     public  static  void  main(String[] args)  throws  ParseException, InterruptedException { 
         Timer timer =  new  Timer(); 
         /**
          * scheduleAtFixedRate方式
          * 设定两秒后执行任务
          */
         timer.scheduleAtFixedRate( new  MyTimerTask1(),  2000 , 1000 );
         /**
          * schedule添加Date参数
          * 设定任务在执行时间执行
          */
//        SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); 
//        Date time = dateFormatter.parse("2016/03/28 14:40:00"); 
//        timer.schedule(new MyTimerTask1(), time);
         //启动MyTimerTask1线程后,主线程休眠五秒钟,给MyTimerTask1五秒的执行时间
         Thread.sleep( 5000 );
         //终止Timer线程
         timer.cancel();
        
}

  JDK 5.0以后推荐使用ScheduledThreadPoolExecutor。关于Timer简单了解即可。


2.ScheduledThreadPoolExecutor

ScheduledThreadPoolExecutor属于Executor Framework,
它除了能处理异常外,还可以以多线程方式执行定时任务。
Timer类是通过单线程来执行所有的TimerTask任务的,如果一个任务的执行过程非常耗时,将会导致其他任务的时效性出现问题。
而 ScheduledThreadPoolExecutor是基于线程池的多线程执行任务,不会存在这样的问题。

通过一个实例学习:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public  class  ScheduledThreadPoolExecutorTest {
 
     public  static  void  main(String[] args) { 
         //获得实例,并且设置它的容量为5个 
         ScheduledThreadPoolExecutor sExecutor= new  ScheduledThreadPoolExecutor( 5 );
         MyTask task =  new  MyTask();
         //隔2秒后开始执行任务,并且在上一次任务开始后隔一秒再执行一次
//      sExecutor.scheduleWithFixedDelay(task, 2, 1, TimeUnit.SECONDS); 
         //隔6秒后执行一次,但只会执行一次
         sExecutor.schedule(task,  6 , TimeUnit.SECONDS);
         /**
          * 和Timer类似,也可以直接在任务的run()方法中调用调度方法停止
          * 这个方法会平滑的关闭调度器,等待所有任务结束
          */
         sExecutor.shutdown();
         
     }
     
     static  class  MyTask  implements  Runnable{
 
         @Override
         public  void  run() {
             System.out.println( "当前执行的线程" +Thread.currentThread().getName());
         }
         
     }
}


3.使用Qurtz

Qurtz的使用非常简单,作为解决方案支持更多的触发机制。

具体的应用可以查看官方文档:http://www.quartz-scheduler.org/documentation/quartz-2.2.x/tutorials/

 


目录
相关文章
|
3月前
|
资源调度 Java
在SchedulerX中,你可以使用`schedulerx.submitTask(taskName)`方法来提交并执行单个任务
【1月更文挑战第7天】【1月更文挑战第34篇】在SchedulerX中,你可以使用`schedulerx.submitTask(taskName)`方法来提交并执行单个任务
20 1
|
Java Spring
@Scheduled 多个定时任务同时执行
这篇文章主要介绍了springBoot @Scheduled实现多个任务同时开始执行,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
734 0
|
6天前
|
Java 调度 Python
解决方案:APScheduler定时任务不执行,报错Run time of job ... was missed by ...
解决方案:APScheduler定时任务不执行,报错Run time of job ... was missed by ...
21 0
解决方案:APScheduler定时任务不执行,报错Run time of job ... was missed by ...
|
Java
使用ScheduledExecutorService线程池创建定时任务
使用ScheduledExecutorService线程池创建定时任务
218 0
|
Java 调度
ScheduledExecutorService:多线程任务调度
ScheduledExecutorService:多线程任务调度
667 0
ScheduledExecutorService:多线程任务调度
|
Java 调度
定时任务@Scheduled 和 异步@Async
定时任务@Scheduled 和 异步@Async
|
Java API 调度
调度线程池ScheduledThreadPoolExecutor的正确使用姿势
调度线程池ScheduledThreadPoolExecutor的正确使用姿势
2737 1
调度线程池ScheduledThreadPoolExecutor的正确使用姿势
|
存储 Java API
调度线程池ScheduledThreadPoolExecutor源码解析
调度线程池ScheduledThreadPoolExecutor源码解析
116 0
调度线程池ScheduledThreadPoolExecutor源码解析
有关使用ScheduledThreadPoolExecutor实现定时处理任务
有关使用ScheduledThreadPoolExecutor实现定时处理任务
105 0
|
Java Maven
仿写@ScheduleLock 定时任务
最近公司在搞分布式的定时任务, 怎么满足分布式的定时任务锁。 我看了大量的开源的代码。 https://github.com/lukas-krecan/ShedLock 感觉老外写的非常的不错。
仿写@ScheduleLock 定时任务