文档章节

定时任务执行利器Timer和ScheduledThreadPoolExecutor使用

j
 java_龙
发布于 2018/01/03 20:42
字数 920
阅读 27
收藏 0

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

定时任务是在指定时间执行程序,或周期性执行计划任务。

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/

© 著作权归作者所有

j
粉丝 75
博文 107
码字总数 139365
作品 0
成都
程序员
私信 提问
java定时工具的辟谣

网络上关于java定时器的文章真的是错误百出,给我的学习造成了很大的困扰,Timer根本就没有线程安全问题,Timer的所有调度方法都和上次任务的结束时间没有关系,TImer和ScheduledThreadPoolExec...

肥肥小浣熊
2017/11/20
0
0
Java定时器_ScheduledThreadPoolExecutor

Java定时器_ScheduledThreadPoolExecutor 延迟任务:在xx秒后执行该任务 周期任务:每xx秒执行一次任务 Timer存在一些缺陷,应该考虑使用ScheduleThreadPoolExecutor 来代替他。 可以通过Sch...

秋风醉了
2015/08/14
1K
0
Java中定时任务的实现:Timer与ScheduledExecutorService的不同

前言 在做后台任务的时候经常需要实现各种各种的定时的,周期性的任务。比如每隔一段时间更新一下缓存之类的。通常周期性的任务都可以使用如下方式实现: class MyTimerThread extends Thre...

wf78728381
2017/10/18
39
0
Timer和ScheduledThreadPoolExecutor的定时任务

1 目录 - Timer和ScheduledThreadPoolExecutor的定时任务 2 调度概述 - 1 说到调度,有最简单的Timer、ScheduledThreadPoolExecutor,又有Spring Task、quartz。 - 2 说到分布式调度,有基于...

乒乓狂魔
2016/09/12
352
0
Timer与ScheduledExecutorService间的抉择

Timer与ScheduledExecutorService间的抉择 java.util.Timer计时器有管理任务延迟执行("如1000ms后执行任务")以及周期性执行("如每500ms执行一次该任务")。 但是,Timer存在一些缺陷,因此你应...

xiaoqiang_sea
2014/04/17
0
0

没有更多内容

加载失败,请刷新页面

加载更多

CountDownLatch、Semaphore等4大并发工具类详解

Java并发工具包 1.并发工具类 提供了比synchronized更加高级的各种同步结构:包括CountDownLatch、CyclicBarrier、Semaphore等,可以实现更加丰富的多线程操作。 2.并发容器 提供各种线程安全...

Java阿七
5分钟前
3
0
general-biz使用教程

general-biz使用教程 1. 技术目标 简化biz层基础业务开发,实现单表基础业务代码简洁易读,通过注解方式实现基础业务实现类托管,项目启动时动态生成,和动态加载到spring容器中。 2. 下载地...

sharelords
23分钟前
3
0
源码分析Kafka 消息拉取流程(文末两张流程图)

本节重点讨论 Kafka 的消息拉起流程。 @TOC 1、KafkaConsumer poll 详解 消息拉起主要入口为:KafkaConsumer#poll方法,其声明如下: public ConsumerRecords<k, v> poll(final Duration t...

中间件兴趣圈
27分钟前
3
0
如何在Java中创建通用数组?

由于Java泛型的实现,因此不能有以下代码: public class GenSet<E> { private E a[]; public GenSet() { a = new E[INITIAL_ARRAY_LENGTH]; // error: generic array crea......

javail
32分钟前
4
0
redis数据类型/键值/服务常用操作、安全设置

Redis数据类型和常用操作 Redis有5中数据类型,分别是string(字符串)、list(链表)、set(集合)、sorted set(有序集合)、hash(哈希) 1.string string为最简单的类型,与Memcached一样,一个key...

asnfuy
43分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部