论坛首页 Java企业应用论坛

在Java中使用定时任务的最佳实践

浏览 8557 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2013-05-05  
之前大部分人在遇到需要使用定时任务的时候首先会想到Timer类,用法一般就是:
new Timer("timer").schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("执行任务");
            }
        }, 1000L, 1000L);


不过在JDK5.0之后就不建议使用这个Timer了,因为它有很多的缺陷。
在新的java.util.concurrent包中的ScheduledExecutorService可以替代这个Timer:
使用方法举例:
ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);
exec.scheduleAtFixedRate(new Runnable() {
    public void run() {
	try{
	    throw new RuntimeException();
	}catch (Exception e){
	    System.out.println("RuntimeException catched");
	}
    }
}, 1000, 5000, TimeUnit.MILLISECONDS);


最后,如果要用到高级功能,比如在某个星期的周五,在国庆节当天的几点几分,在每天凌晨几点几分执行之类的定时任务,就需要用到大名鼎鼎的Quartz框架了,一般用法:
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler sched = sf.getScheduler();
JobDetail job = newJob(SimpleJob.class)
	.withIdentity("job1", "group1")
	.build();

CronTrigger trigger = newTrigger()
	.withIdentity("trigger1", "group1")
	.withSchedule(cronSchedule("0/20 * * * * ?"))
	.build();

Date ft = sched.scheduleJob(job, trigger);
sched.start();


据我所知这个就是定时任务的最佳实践了,不知道大家还有没有更好的建议  
   发表时间:2013-05-06  
在JDK5.0之后就不建议使用这个Timer了,因为它有很多的缺陷。 
-------------------------------\
你这么说感觉不负责任啊。各大经典java都这么用的jdk1.6  effictiveJava
1:有什么缺陷
2:ScheduledExecutorService有什么优势
你这么写出来才是一篇好文章啊,这么写谁明白?
0 请登录后投票
   发表时间:2013-05-06  
继续观察。。。
0 请登录后投票
   发表时间:2013-05-06  
a possible option: use timer from netty lib.
0 请登录后投票
   发表时间:2013-05-06   最后修改:2013-05-06
yuanmengchong 写道
在JDK5.0之后就不建议使用这个Timer了,因为它有很多的缺陷。 
-------------------------------\
你这么说感觉不负责任啊。各大经典java都这么用的jdk1.6  effictiveJava
1:有什么缺陷
2:ScheduledExecutorService有什么优势
你这么写出来才是一篇好文章啊,这么写谁明白?


哦,不好意思,确实没有解释的比较详细。

第1:Timer在执行所有定时任务的时候只会创建一个线程。如果某个任务执行时间过长,那么将破坏其他TimeTask的定时精确性。

第2:如果TimerTask抛出一个UncheckedException,那么Timer将表现出很挫的行为。Timer并不捕获异常,因此当TimerTask抛出UncheckedException时候将终止定时线程,比如常见的一个NullPointerException。这种情况下,Timer不会恢复线程执行,而是会错误的任务整个Timer都取消掉。因此,已经被调度但尚未执行的Task将不会执行了,新的任务也不会调度,也就是常见的线程泄露。

而ScheduledThreadPoolExecutor能正确处理这些表现出错误行为的任务。

因此,如果您的JDK是5.0以上的,那么建议不要使用过时的Timer类了。
0 请登录后投票
   发表时间:2013-05-07  
<<Java Concurrency in Practice>> 一书有很好的介绍。
0 请登录后投票
   发表时间:2013-05-08  
用crontab
0 请登录后投票
   发表时间:2013-05-08  
Quartz确实是一个非常非常强大的任务框架。
0 请登录后投票
   发表时间:2013-05-08   最后修改:2013-05-08
写道
Quartz确实是一个非常非常强大的任务框架。

 

是很强大,但是当你在实际项目中使用时,你会发现它还是远远不够的,比如当一个系统有很多计划任务要管理时,你会觉得很崩溃的!幸运的是,Quartz提供了一个基于WEB的可视化任务管理器,不幸的是,这个是要收费的!

0 请登录后投票
   发表时间:2013-05-09  
hellostory 写道
写道
Quartz确实是一个非常非常强大的任务框架。

 

是很强大,但是当你在实际项目中使用时,你会发现它还是远远不够的,比如当一个系统有很多计划任务要管理时,你会觉得很崩溃的!幸运的是,Quartz提供了一个基于WEB的可视化任务管理器,不幸的是,这个是要收费的!

 

这个商业Quartz产品是一套完整的产品线,并不仅仅是“WEB的可视化任务管理器”那么简单,它的竞争对手BMC的Control-M(X)系列,单个任务的收费就达到6欧元,而Quartz的商业产品价格要比BMC便宜得多。

0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics