Java 如何安排任务定期运行?

Java 如何安排任务定期运行?,java,timer,schedule,Java,Timer,Schedule,我尝试了一些代码来实现一个预定的任务,并想出了这些代码 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

我尝试了一些代码来实现一个预定的任务,并想出了这些代码

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分钟,我只得到一个输出…我如何解决这个问题

public void schedule(TimerTask task,long delay)
计划在指定的延迟后执行指定的任务

你想要:

public void schedule(TimerTask task, long delay, long period)
将指定的任务安排为重复固定延迟执行,从指定延迟后开始。随后的执行大约以指定的时间间隔定期进行。

使用

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

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

参数:

  • 任务-要计划的任务
  • 延迟-执行任务前的延迟(毫秒)
  • period—连续执行任务之间的时间(以毫秒为单位)
抛出:

  • IllegalArgumentException-如果延迟为负,或延迟+System.currentTimeMillis()为负
  • IllegalStateException-如果任务已计划或取消,则计时器已取消,或计时器线程已终止
  • ScheduledExecutorService
    优于
    定时器的优点
    我希望为您提供一种替代
    定时器
    的方法,使用-,实现接口。根据“Java in Concurrency”,它比Timer类有一些优势:

    计时器
    只创建一个用于执行计时器任务的线程。如果 计时器任务运行时间太长,影响其他任务的计时精度
    TimerTask
    可能会受到影响。如果计划运行定期的
    TimerTask
    每10毫秒和另一个计时器任务运行40毫秒,循环 任务(取决于它是按固定速率还是按 固定延迟)在 长时间运行的任务完成,或完全“错过”四次调用。 计划线程池通过允许您提供 用于执行延迟和定期任务的多个线程

    计时器的另一个问题是,如果
    TimerTask
    抛出未经检查的异常,则计时器的性能会很差。也称为“螺纹泄漏”

    计时器线程没有捕获异常,因此未选中 从
    TimerTask
    引发的异常终止计时器线程。计时器 在这种情况下也不会复活线程;相反,它 错误地认为整个计时器已取消。在这种情况下,, 已计划但尚未执行的TimerTask永远不会 运行,则无法计划新任务


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

    scheduleAtFixedRate没有解决只获取一次输出的问题。@JamesA.N.Stauffer,他需要重复输出,而不是一次。是的,但重复只需添加第三个参数即可实现——不需要更改方法。@st0le。考虑下面的类比。提问者说“天是蓝的”,你说的是“不,草是绿的。”-如果他的问题是“什么是固定速率重复”,那么你的答案将是理想的。如果你希望它是某个上下限范围内的随机速率呢?计时器的另一个问题是改变系统时钟,它与timerQuartz调度程序发生冲突,帮助Java应用程序调度作业/任务,使其在指定的日期和时间运行,这些类已被替换为。有关详细信息,请参见JavaDoc上的第7段。
    timer.scheduleAtFixedRate( new Task(), 1000,3000); 
    
    timer.scheduleAtFixedRate( new Task(), 1000,3000);