如何安排任务定期运行?

Vim*_*deo 73 java schedule timer

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

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);   
   }
}
Run Code Online (Sandbox Code Playgroud)

我的输出:

1  :  Mahendra Singh
Run Code Online (Sandbox Code Playgroud)

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

Ale*_*ndr 75

优势ScheduledExecutorService超过Timer

我希望为您提供一种替代Timer方法 - ScheduledThreadPoolExecutor,一个ScheduledExecutorService接口的实现.根据"Java in Concurrency",它比Timer类有一些优点:

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

Timer的另一个问题是,如果TimerTask 抛出未经检查的异常,它的行为很差.另外,称为"线程泄漏"

Timer线程没有捕获异常,因此从TimerTask终止定时器线程的未经检查的异常终止.在这种情况下,Timer也不会恢复线程; 相反,它错误地假设整个Timer被取消了.在这种情况下,已经调度但尚未执行的TimerTasks永远不会运行,并且无法安排新任务.

而另一项建议,如果你需要建立自己的调度服务,您仍然可以通过使用以充分利用图书馆DelayQueue,一个BlockingQueue提供的调度功能的实现ScheduledThreadPoolExecutor.A DelayQueue管理延迟对象的集合.延迟具有与之关联的延迟时间:DelayQueue允许您仅在其延迟已过期时获取元素.DelayQueue按照与延迟相关的时间从对象返回对象.

  • 计时器的另一个问题是,在更改系统时钟时,它会与计时器混淆 (4认同)

st0*_*0le 72

使用 timer.scheduleAtFixedRate

public void scheduleAtFixedRate(TimerTask task,
                                long delay,
                                long period)
Run Code Online (Sandbox Code Playgroud)

在指定的延迟之后开始,为重复的固定速率执行安排指定的任务.随后的执行大约定期进行,以指定的时间段分开.
在固定速率执行中,每次执行都是相对于初始执行的预定执行时间进行调度的.如果由于任何原因(例如垃圾收集或其他后台活动)延迟执行,则会快速连续执行两次或更多次执行以"赶上".从长远来看,执行的频率将恰好是指定时间段的倒数(假设Object.wait(long)下的系统时钟是准确的).

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

参数:

  • 任务 - 要安排的任务.
  • 延迟 - 执行任务前的延迟(以毫秒为单位).
  • period - 连续任务执行之间的时间(以毫秒为单位).

抛出:

  • IllegalArgumentException - 如果延迟为负数,或者延迟+ System.currentTimeMillis()为负数.
  • IllegalStateException - 如果已安排或取消任务,则取消计时器或终止计时器线程.

  • scheduleAtFixedRate不解决他只获取输出一次的问题. (4认同)
  • 是的,但重复只是通过添加第三个参数来实现 - 不需要更改方法. (3认同)
  • @ st0le.考虑以下类比.提问者说"天空是蓝色的",你说"不,草是绿色的." - 如果他的问题是"什么是固定利率重复",你的答案将是理想的. (2认同)

yur*_*rib 15

public void schedule(TimerTask task,long delay)
Run Code Online (Sandbox Code Playgroud)

在指定的延迟后安排指定的任务执行.

你要:

public void schedule(TimerTask task, long delay, long period)
Run Code Online (Sandbox Code Playgroud)

在指定的延迟之后开始,为重复的固定延迟执行安排指定的任务.随后的执行大约以规定的时间间隔进行,并以指定的时间段分隔.