如何计划任务定期运行?优势ScheduledExecutorServiceTimer

2022-08-31 12:21:14

我正在尝试一些代码来实现计划任务,并提出了这些代码 。

import java.util.*;

class Task extends TimerTask {


    int count = 1;

    // run is a abstract method that defines task performed at scheduled time.
    public void run() {
        System.out.println(count+" : Mahendra Singh");
        count++;
    }
}

class TaskScheduling {

   public static void main(String[] args) {
       Timer timer = new Timer();


       // Schedule to run after every 3 second(3000 millisecond)
       timer.schedule( new Task(), 3000);   
   }
}

我的输出 :

1  :  Mahendra Singh

我期望编译器以3秒的周期间隔打印一系列Mahendra Singh,但尽管等待了大约15分钟,我只能得到一个输出......我该如何解决这个问题?


答案 1

优势ScheduledExecutorServiceTimer

我希望为您提供一种使用的替代方法 - ScheduledThreadPoolExecutorScheduledExecutorService接口的实现。与Timer类相比,它具有一些优势,根据“并发中的Java”:Timer

A 仅创建一个用于执行计时器任务的线程。如果计时器任务运行时间过长,则其他计时器任务的计时准确性可能会受到影响。如果计划每 10 毫秒运行一次定期任务,而另一个计时器任务需要 40 毫秒才能运行,则重复执行的任务(取决于它是以固定速率还是固定延迟计划)在长时间运行的任务完成后快速连续调用四次,或者完全“错过”四次调用。计划线程池通过允许您提供多个线程来执行延迟和定期任务,从而解决了此限制。TimerTimerTaskTimerTask

Timer 的另一个问题是,如果引发未经检查的异常,它的行为会很差。也称为“螺纹泄漏”TimerTask

定时器线程不捕获异常,因此从 引发的未经检查的异常将终止计时器线程。在这种情况下,计时器也不会复活线程;相反,它错误地假设整个计时器已被取消。在这种情况下,已计划但尚未执行的 TimerTask 永远不会运行,并且无法计划新任务。TimerTask

另一个建议是,如果您需要构建自己的调度服务,您仍然可以通过使用 ,一种提供 调度功能的实现来利用该库。A 管理延迟对象的集合。延迟具有与之关联的延迟时间:仅当元素的延迟已过期时,才允许您获取该元素。对象按与其延迟关联的时间从 有序返回。DelayQueueBlockingQueueScheduledThreadPoolExecutorDelayQueueDelayQueueDelayQueue


答案 2

Use timer.scheduleAtFixedRate

public void scheduleAtFixedRate(TimerTask task,
                                long delay,
                                long period)

将指定的任务安排在指定的延迟之后开始重复执行固定速率。随后的执行以大约固定的时间间隔进行,间隔指定的时间段。
在固定速率执行中,每次执行都是相对于初始执行的计划执行时间来安排的。如果执行因任何原因(例如垃圾回收或其他后台活动)而延迟,则两个或多个执行将快速连续发生以“赶上”。从长远来看,执行频率将完全是指定时间段的倒数(假设 Object.wait(long) 底层的系统时钟是准确的)。

固定速率执行适用于对绝对时间敏感的定期活动,例如每小时按一小时响铃,或在特定时间每天运行计划维护。它还适用于执行固定次数的执行的总时间很重要的重复性活动,例如每秒滴答一次的倒数计时器,持续十秒。最后,固定速率执行适用于调度多个重复计时器任务,这些任务必须彼此保持同步。

参数:

  • 任务 - 要计划的任务。
  • delay - 执行任务之前的毫秒级延迟。
  • 周期 - 连续任务执行之间的时间(以毫秒为单位)。

抛出:

  • IllegalArgumentException - 如果 delay 为负,或者 delay + System.currentTimeMillis() 为负。
  • IllegalStateException - 如果任务已计划或取消,则计时器已取消,或者计时器线程已终止。