ScheduledExecutorService和timer的异同

先来个传统的Timer的例子:

package com.jerry.concurrency;  
 
import java.text.ParseException;  
import java.text.SimpleDateFormat;  
import java.util.Date;  
import java.util.Timer;  
import java.util.TimerTask;  
 
public class TraditionalTask {  
 
 
 public static void main(String[] args) throws ParseException {  
        Timer myTimer = new Timer();  
        myTimer.schedule(new Worker(), 1000);//1秒后执行 
//      2012-02-28 09:58:00执行 
        myTimer.schedule(new Worker(), new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2012-02-28 09:58:00"));  
        myTimer.schedule(new Worker(), 5000,1000);//5秒后执行 每一秒执行一次 
//      2012-02-28 09:58:00执行一次 以后每秒执行一次,如果设定的时间点在当前时间之前,任务会被马上执行,然后开始按照设定的周期定时执行任务 
        myTimer.schedule(new Worker(), new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2012-02-28 09:58:00"),1000);  
        myTimer.scheduleAtFixedRate(new Worker(), 5000,1000);//5秒后执行 每一秒执行一次 如果该任务因为某些原因(例如垃圾收集)而延迟执行,那么接下来的任务会尽可能的快速执行,以赶上特定的时间点 
        myTimer.scheduleAtFixedRate(new Worker(), new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2012-02-28 09:58:00"),1000);//和上个类似 
    }  
}  
 
 
class Worker extends TimerTask {  
 
 @Override 
 public void run() {  
 
        System.out.println("我被执行了!"+"时间是:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));  
    }  
 
}  

传统的timer的缺点:Timer对任务的调度是基于绝对时间的;所有的TimerTask只有一个线程TimerThread来执行,因此同一时刻只有一个TimerTask在执行;任何一个TimerTask的执行异常都会导致Timer终止所有任务;由于基于绝对时间并且是单线程执行,因此在多个任务调度时,长时间执行的任务被执行后有可能导致短时间任务快速在短时间内被执行多次或者干脆丢弃多个任务。

ScheduledExecutorService克服了上述缺点,例子如下:

<span style="font-family:Verdana, Geneva, Arial, Helvetica, sans-serif;font-size:13px;">package com.jerry.concurrency;  
 
 
import java.util.concurrent.Executors;  
import java.util.concurrent.ScheduledExecutorService;  
import java.util.concurrent.TimeUnit;  
 
 
 
 
public class TestScheduledExecutorService{  
 public static void main(String[] args) throws Exception{  
        ScheduledExecutorService execService =   Executors.newScheduledThreadPool(3);  
 // 5秒后开始执行 每个2秒执行一次,如果有的任务执行要花费比其周期更长的时间,则将推迟后续执行,但不会同时执行 
//        每次相隔相同的时间执行任务,如果任务的执行时间比周期还长,那么下一个任务将立即执行 
        execService.scheduleAtFixedRate(new Runnable() {  
 public void run() {  
                System.out.println("任务:"+Thread.currentThread().getName()+" 执行了,时间为: "+System.currentTimeMillis());  
 try {  
                    Thread.sleep(1000L);  
                } catch (Exception e) {  
                    e.printStackTrace();  
                }  
            }  
        }, 5, 2, TimeUnit.SECONDS);  
 //5秒后开始执行 每个2秒执行一次,保证固定的延迟为2秒 下一个任务的开始时间与上一个任务的结束时间间隔相同 
        execService.scheduleWithFixedDelay(new Runnable() {  
 public void run() {  
                System.out.println("任务:"+Thread.currentThread().getName()+"执行了,时间为:"+System.currentTimeMillis());  
 try {  
                    Thread.sleep(1000L);  
                } catch (Exception e) {  
                    e.printStackTrace();  
                }  
            }  
        }, 5, 2, TimeUnit.SECONDS);  
        Thread.sleep(10000L);  
        execService.shutdown();  
    }  
}  
</span>  

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏葡萄城控件技术团队

C#开发人员应该知道的13件事情

本文讲述了C#开发人员应该了解到的13件事情,希望对C#开发人员有所帮助。 1. 开发过程 开发过程是错误和缺陷开始的地方。使用工具可以帮助你在发布之后,解决掉...

24890
来自专栏新智元

Go 2.0发布在即,程序员有太多话要说

Go语言的开发者正着手准备开发2.0版本,并从以下三个方面发布了初步的设计方案(非官方正式版),以供社区开展讨论:

84110
来自专栏函数式编程语言及工具

泛函编程(18)-泛函库设计-并行运算组件库

    作为专业的编程人员,我们经常会因为工作需要建立一些工具库。所谓工具库就是针对工作上经常会遇到的一些共性问题预先编制的由一整套函数所组成的函数库。通常这些...

17570
来自专栏Android机动车

设计模式——代理模式

现在有个非常流行的程序叫做面向切面编程(AOP),其核心就是采用了动态代理的方式。怎么用?Java为我们提供了一个便捷的动态代理接口 InvocationHan...

10610
来自专栏编程坑太多

Callable接口实现多线程,生产者消费者问题,多线下载(复制)文件

19040
来自专栏C/C++基础

CVTE2016春季实习校招技术一面回忆(C++后台开发岗)

2016.3.15,参加了CVTE的技术面,很不幸,我和我的两位小伙伴均跪在了一面。先将当日的面试内容汇总如下,供后来者参考。我们三人各自也都总结了失败的原因,...

6810
来自专栏黑泽君的专栏

java多线程、集合和IO面试题_02

15710
来自专栏chenssy

【死磕Java并发】—–J.U.C之并发工具类:Exchanger

前面三篇博客分别介绍了CyclicBarrier、CountDownLatch、Semaphore,现在介绍并发工具类中的最后一个Exchange。Exchan...

34260
来自专栏后端沉思录

并行执行任务

在app列表首页,展示多个item,并有分页;而每个item里后台都会调用一个http请求,判断当前item的状态

9820
来自专栏大内老A

ASP.NET MVC下的四种验证编程方式

ASP.NET MVC采用Model绑定为目标Action生成了相应的参数列表,但是在真正执行目标Action方法之前,还需要对绑定的参数实施验证以确保其有效性...

23770

扫码关注云+社区

领取腾讯云代金券