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

本文对比了Java中Timer与ScheduledExecutorService的优劣,并推荐在JDK5.0及以上版本使用后者来实现更稳定可靠的定时任务。同时介绍了如何利用Quartz框架实现复杂周期的定时任务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

之前大部分人在遇到需要使用定时任务的时候首先会想到Timer类,用法一般就是: 
Java代码   收藏代码
  1. new Timer("timer").schedule(new TimerTask() {  
  2.             @Override  
  3.             public void run() {  
  4.                 System.out.println("执行任务");  
  5.             }  
  6.         }, 1000L, 1000L);  


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

理由: 
第1:Timer在执行所有定时任务的时候只会创建一个线程。如果某个任务执行时间过长,那么将破坏其他TimeTask的定时精确性。 
第2:如果TimerTask抛出一个UncheckedException,那么Timer将表现出很挫的行为。Timer并不捕获异常,因此当TimerTask抛出UncheckedException时候将终止定时线程,比如常见的一个NullPointerException。这种情况下,Timer不会恢复线程执行,而是会错误的任务整个Timer都取消掉。因此,已经被调度但尚未执行的Task将不会执行了,新的任务也不会调度,也就是常见的线程泄露。 
而ScheduledThreadPoolExecutor能正确处理这些表现出错误行为的任务。 

因此,如果您的JDK是5.0以上的,那么建议不要使用过时的Timer类了。


最后,如果要用到高级功能,比如在某个星期的周五,在国庆节当天的几点几分,在每天凌晨几点几分执行之类的定时任务,就需要用到大名鼎鼎的Quartz框架了,一般用法: 
Java代码   收藏代码
  1. SchedulerFactory sf = new StdSchedulerFactory();  
  2. Scheduler sched = sf.getScheduler();  
  3. JobDetail job = newJob(SimpleJob.class)  
  4.     .withIdentity("job1""group1")  
  5.     .build();  
  6.   
  7. CronTrigger trigger = newTrigger()  
  8.     .withIdentity("trigger1""group1")  
  9.     .withSchedule(cronSchedule("0/20 * * * * ?"))  
  10.     .build();  
  11.   
  12. Date ft = sched.scheduleJob(job, trigger);  
  13. sched.start();  

据我所知这个就是定时任务的最佳实践了,不知道大家还有没有更好的建议  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值