79

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

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

4

4 回答 4

83

ScheduledExecutorService超过的优势Timer

我希望为您提供Timer使用ScheduledThreadPoolExecutor的替代方法,它是ScheduledExecutorService接口的实现。根据“Java in Concurrency”,它比 Timer 类有一些优势:

ATimer只创建一个线程来执行定时器任务。如果一个定时器任务运行时间过长,其他的定时精度 TimerTask就会受到影响。如果一个循环TimerTask计划每 10 毫秒运行一次,而另一个 Timer-Task 需要 40 毫秒来运行,则循环任务(取决于它是以固定速率还是固定延迟安排的)在长时间后快速连续调用四次。 running 任务完成,或完全“错过”四个调用。计划线程池通过允许您提供多个线程来执行延迟和定期任务来解决此限制。

Timer 的另一个问题是,如果 aTimerTask 抛出未经检查的异常,它的行为就会很差。也称为“线程泄漏”

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

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

于 2010-12-28T09:11:20.803 回答
79

采用timer.scheduleAtFixedRate

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

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

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

参数:

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

抛出:

  • IllegalArgumentException - 如果延迟为负,或者延迟 + System.currentTimeMillis() 为负。
  • IllegalStateException - 如果任务已经安排或取消,定时器被取消,或定时器线程终止。
于 2010-12-28T08:01:02.703 回答
15
public void schedule(TimerTask task,long delay)

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

你要:

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

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

于 2010-12-28T06:54:33.477 回答
2
timer.scheduleAtFixedRate( new Task(), 1000,3000); 
于 2016-03-03T07:54:52.320 回答