我如何安排一个任务定期运行?

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

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,但是尽pipe等了大约15分钟,我只能得到一个输出……我该如何解决这个问题呢?

使用timer.scheduleAtFixedRate

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

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

固定利率执行适用于对绝对时间敏感的周期性活动,例如每小时每小时响一声,或在特定时间每天运行计划维护。 对于执行固定次数执行的总时间很重要的周期性活动也是适当的,例如倒数计时器每秒钟滴答一次,持续十秒钟。 最后,固定速率执行适用于调度多个必须保持相互同步的重复计时器任务。

参数:

  • 任务 – 要安排的任务。
  • 延迟 – 以毫秒为单位执行任务之前的延迟。
  • 以连续任务执行为单位的周期时间(以毫秒为单位)。

抛出:

  • IllegalArgumentException – 如果延迟为负数,或者延迟+ System.currentTimeMillis()为负数。
  • IllegalStateException – 如果任务已经被调度或取消,定时器被取消或定时器线程被终止。

ScheduledExecutorService的

我希望为您提供Timer的替代方法,使用ScheduledThreadPoolExecutor ,这是ScheduledExecutorService接口的一个实现。 它比Timer类(来自“Java in Concurrency”)有一些优点:

一个Timer只创build一个执行计时器任务的线程。 如果计时器任务运行时间过长,则其他TimerTasks的计时准确度可能会受到影响。 如果一个循环的TimerTask计划每10毫秒运行一次,另一个计时器任务需要40毫秒才能运行,则循环任务(取决于它是按固定速率还是固定延迟计划的)在长时间之后连续快速连续调用四次运行任务完成,或完全“错过”四个调用。 计划的线程池通过让您提供执行延期和周期性任务的多个线程来解决这个限制。

定时器的另一个问题是,如果一个TimerTask抛出一个未经检查的exception,它performance不佳。 Timer线程不捕获exception,所以从TimerTask抛出的未经检查的exception终止计时​​器线程。 在这种情况下,定时器也不会复位线程; 相反,它错误地假定整个计时器被取消。 在这种情况下,已经调度但尚未执行的TimerTasks永远不会运行,并且不能调度新任务。 (这个问题叫做“线程泄漏”)。

另一个build议是,如果您需要构build自己的调度服务,则仍然可以使用DelayQueue(一个提供ScheduledThreadPoolExecutor的调度function的BlockingQueue实现)来利用该库。 DelayQueuepipe理Delayed对象的集合。 Delayed具有与之相关的延迟时间:DelayQueue允许您只有在延迟已经到期的情况下才采取某个元素。 对象从DelayQueue返回,这个DelayQueue是按照延迟时间sorting的。

 public void schedule(TimerTask task,long delay) 

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

你要:

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

计划指定的任务重复执行固定延迟 ,从指定的延迟开始。 随后的处决大致按照规定的时间间隔进行。

你可以使用Quartz

Quartz调度器也是一个解决scheme,首先你做Quartz Job类。

Quartz工作是定义你想要运行的

 package com.blogspot.geekonjava.quartz; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.quartz.JobKey; public class QuartzJob implements Job { public void execute(JobExecutionContext context) throws JobExecutionException { JobKey jobKey = context.getJobDetail().getKey(); System.out.println("Quartz" + "Job Key " + jobKey); } } 

现在你需要制作Quartz Trigger

Quartz中有两种types的触发器

SimpleTrigger – 允许设置开始时间,结束时间,重复间隔。

 Trigger trigger = newTrigger().withIdentity("TriggerName", "Group1") .withSchedule(SimpleScheduleBuilder.simpleSchedule() .withIntervalInSeconds(10).repeatForever()).build(); 

CronTrigger – 允许Unix cronexpression式指定运行作业的date和时间。

 Trigger trigger = newTrigger() .withIdentity("TriggerName", "Group2") .withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ?")).build(); 

调度程序类将作业触发器链接在一起并执行。

 Scheduler scheduler = new StdSchedulerFactory().getScheduler(); scheduler.start(); scheduler.scheduleJob(job, trigger); 

完整的例子,你可以看到这里

timer.scheduleAtFixedRate(new Task(),1000,3000);

为此Java有Timer和TimerTask类,但它是什么?

  • java.util.Timer是一个实用工具类,可以用来安排将来某个时间执行的线程。 Java Timer类可用于调度一次运行的任务或定期运行的任务。
  • java.util.TimerTask是一个实现Runnable接口的抽象类,我们需要扩展这个类来创build我们自己的可以使用java Timer类来调度的TimerTask。

你可以从GeekonJava查看完整的教程

 TimerTask timerTask = new MyTimerTask(); //running timer task as daemon thread Timer timer = new Timer(true); timer.scheduleAtFixedRate(timerTask, 0, 10*1000);