加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_泰州站长网 (http://www.0523zz.com/)- 视觉智能、AI应用、CDN、行业物联网、智能数字人!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

在Java中使用定时任务的优秀实践

发布时间:2021-12-13 12:40:49 所属栏目:PHP教程 来源:互联网
导读:之前大部分人在遇到需要使用定时任务的时候首先会想到Timer类,用法一般就是: new Timer(timer).schedule(new TimerTask() { @Override public void run() { System.out.println(执行任务); } }, 1000L, 1000L); 不过在JDK5.0之后就不建议使用这个Timer了,

之前大部分人在遇到需要使用定时任务的时候首先会想到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);
 
理由:
 
第1:Timer在执行所有定时任务的时候只会创建一个线程。如果某个任务执行时间过长,那么将破坏其他TimeTask的定时精确性。
 
第2:如果TimerTask抛出一个UncheckedException,那么Timer将表现出很挫的行为。Timer并不捕获异常,因此当TimerTask抛出UncheckedException时候将终止定时线程,比如常见的一个NullPointerException。这种情况下,Timer不会恢复线程执行,而是会错误的任务整个Timer都取消掉。因此,已经被调度但尚未执行的Task将不会执行了,新的任务也不会调度,也就是常见的线程泄露。
 
而ScheduledThreadPoolExecutor能正确处理这些表现出错误行为的任务。
 
因此,如果您的JDK是5.0以上的,那么建议不要使用过时的Timer类了。
 
最后,如果要用到高级功能,比如在某个星期的周五,在国庆节当天的几点几分,在每天凌晨几点几分执行之类的定时任务,就需要用到大名鼎鼎的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();
 
据我所知这个就是定时任务的最佳实践了,不知道大家还有没有更好的建议。

(编辑:云计算网_泰州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读