如何安排任务以周期性的间隔运行?

时间:2021-02-23 14:39:06

I was trying some codes to implement a scheduled task and came up with these codes .

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

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);   
   }
}

My output :

我的输出:

1  :  Mahendra Singh

I expected the compiler to print a series of Mahendra Singh at periodic interval of 3 s but despite waiting for around 15 minutes, I get only one output...How do I solve this out?

我希望编译器能够以3秒的周期间隔打印出一系列的Mahendra Singh,但是尽管我等待了大约15分钟,我只得到了一个输出……我怎么解出来?

7 个解决方案

#1


61  

Use timer.scheduleAtFixedRate

使用timer.scheduleAtFixedRate

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

Schedules the specified task for repeated fixed-rate execution, beginning after the specified delay. Subsequent executions take place at approximately regular intervals, separated by the specified period.
In fixed-rate execution, each execution is scheduled relative to the scheduled execution time of the initial execution. If an execution is delayed for any reason (such as garbage collection or other background activity), two or more executions will occur in rapid succession to "catch up." In the long run, the frequency of execution will be exactly the reciprocal of the specified period (assuming the system clock underlying Object.wait(long) is accurate).

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

Fixed-rate execution is appropriate for recurring activities that are sensitive to absolute time, such as ringing a chime every hour on the hour, or running scheduled maintenance every day at a particular time. It is also appropriate for recurring activities where the total time to perform a fixed number of executions is important, such as a countdown timer that ticks once every second for ten seconds. Finally, fixed-rate execution is appropriate for scheduling multiple repeating timer tasks that must remain synchronized with respect to one another.

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

Parameters:

参数:

  • task - task to be scheduled.
  • 任务-任务计划。
  • delay - delay in milliseconds before task is to be executed.
  • 延迟——任务执行前的毫秒延迟。
  • period - time in milliseconds between successive task executions.
  • 周期-连续任务执行之间的毫秒数。

Throws:

抛出:

  • IllegalArgumentException - if delay is negative, or delay + System.currentTimeMillis() is negative.
  • IllegalArgumentException—如果延迟为负,或delay + System.currentTimeMillis()为负。
  • IllegalStateException - if task was already scheduled or cancelled, timer was cancelled, or timer thread terminated.
  • IllegalStateException—如果任务已经被调度或取消,则会取消计时器或终止计时器线程。

#2


67  

ScheduledExecutorService

I wish to offer you an alternative to Timer using - ScheduledThreadPoolExecutor, an implementation of the ScheduledExecutorService interface. It has some advantages over the Timer class (from "Java in Concurrency"):

我希望向您提供一个使用ScheduledThreadPoolExecutor的计时器替代方法,它是ScheduledExecutorService接口的实现。它与定时器类(从“Java并发”)相比有一些优势:

A Timer creates only a single thread for executing timer tasks. If a timer task takes too long to run, the timing accuracy of other TimerTasks can suffer. If a recurring TimerTask is scheduled to run every 10 ms and another Timer-Task takes 40 ms to run, the recurring task either (depending on whether it was scheduled at fixed rate or fixed delay) gets called four times in rapid succession after the long-running task completes, or "misses" four invocations completely. Scheduled thread pools address this limitation by letting you provide multiple threads for executing deferred and periodic tasks.

计时器仅为执行计时器任务创建一个线程。如果一个计时器任务运行的时间太长,那么其他计时器任务的计时精度就会受到影响。如果反复出现的TimerTask调度运行每10和另一个女士Timer-Task花40 ms,要么重复任务(取决于是否安排在固定利率或固定延迟)在快速连续四次被调用长时间运行的任务完成后,或者完全“错过”四个调用。计划的线程池通过允许您为执行延迟任务和周期任务提供多个线程来解决这个限制。

Another problem with Timer is that it behaves poorly if a TimerTask throws an unchecked exception. The Timer thread doesn't catch the exception, so an unchecked exception thrown from a TimerTask terminates the timer thread. Timer also doesn't resurrect the thread in this situation; instead, it erroneously assumes the entire Timer was cancelled. In this case, TimerTasks that are already scheduled but not yet executed are never run, and new tasks cannot be scheduled. (This problem, called "thread leakage").

Timer的另一个问题是,如果TimerTask抛出一个未检查的异常,那么它的行为会很糟糕。计时器线程不会捕获异常,因此从TimerTask抛出的未检查异常将终止计时器线程。Timer在这种情况下也不会恢复线程;相反,它错误地假设整个计时器被取消。在这种情况下,已经调度但尚未执行的TimerTasks将永远不会运行,新的任务将无法调度。(这个问题叫做“漏线”)

And another recommendation if you need to build your own scheduling service, you may still be able to take advantage of the library by using a DelayQueue, a BlockingQueue implementation that provides the scheduling functionality of ScheduledThreadPoolExecutor. A DelayQueue manages a collection of Delayed objects. A Delayed has a delay time associated with it: DelayQueue lets you take an element only if its delay has expired. Objects are returned from a DelayQueue ordered by the time associated with their delay.

另外,如果需要构建自己的调度服务,还可以使用DelayQueue,这是一个block queue实现,它提供ScheduledThreadPoolExecutor的调度功能。DelayQueue管理延迟对象的集合。延迟具有与之相关的延迟时间:DelayQueue允许您仅在元素的延迟已过期时才获取元素。对象从与延迟相关联的时间排序的DelayQueue返回。

#3


13  

public void schedule(TimerTask task,long delay)

Schedules the specified task for execution after the specified delay.

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

you want:

你想要的:

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

Schedules the specified task for repeated fixed-delay execution, beginning after the specified delay. Subsequent executions take place at approximately regular intervals separated by the specified period.

将指定的任务安排为重复的固定延迟执行,从指定的延迟开始。随后的执行以大约有规律的间隔进行,间隔由指定的周期分隔。

#4


4  

You can use Quartz

您可以使用石英

#5


4  

Quartz scheduler is also a solution and firstly you make Quartz Job class.

Quartz调度器也是一种解决方案,首先创建Quartz作业类。

Quartz job is defined what you want to run

Quartz job定义了您想要运行的内容。

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);
        }
}

Now you need to make Quartz Trigger

现在你需要做石英触发器

There are two types of triggers in Quartz

Quartz有两种类型的触发器

SimpleTrigger – Allows to set start time, end time, repeat interval.

SimpleTrigger—允许设置开始时间、结束时间、重复间隔。

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

CronTrigger – Allows Unix cron expression to specify the dates and times to run your job.

CronTrigger——允许Unix cron表达式指定运行作业的日期和时间。

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

Scheduler class links both Job and Trigger together and execute it.

Scheduler类将作业和触发器链接在一起并执行它。

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

Full Example you can see here

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

#6


2  

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

计时器。scheduleAtFixedRate(新任务()、1000、3000);

#7


1  

For this purpose Java has Timer and TimerTask class but what is it ?

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

  • java.util.Timer is a utility class that can be used to schedule a thread to be executed at certain time in future. Java Timer class can be used to schedule a task to be run one-time or to be run at regular intervals.
  • java.util。Timer是一个实用程序类,可以用来调度将来某个时间要执行的线程。Java Timer类可用于调度一次运行或定期运行的任务。
  • java.util.TimerTask is an abstract class that implements Runnable interface and we need to extend this class to create our own TimerTask that can be scheduled using java Timer class.
  • java.util。TimerTask是一个实现Runnable接口的抽象类,我们需要扩展这个类来创建我们自己的TimerTask,它可以使用java Timer类进行调度。

You can check full tutorial from GeekonJava

您可以查看GeekonJava的完整教程

TimerTask timerTask = new MyTimerTask();

//running timer task as daemon thread

Timer timer = new Timer(true);

timer.scheduleAtFixedRate(timerTask, 0, 10*1000);

#1


61  

Use timer.scheduleAtFixedRate

使用timer.scheduleAtFixedRate

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

Schedules the specified task for repeated fixed-rate execution, beginning after the specified delay. Subsequent executions take place at approximately regular intervals, separated by the specified period.
In fixed-rate execution, each execution is scheduled relative to the scheduled execution time of the initial execution. If an execution is delayed for any reason (such as garbage collection or other background activity), two or more executions will occur in rapid succession to "catch up." In the long run, the frequency of execution will be exactly the reciprocal of the specified period (assuming the system clock underlying Object.wait(long) is accurate).

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

Fixed-rate execution is appropriate for recurring activities that are sensitive to absolute time, such as ringing a chime every hour on the hour, or running scheduled maintenance every day at a particular time. It is also appropriate for recurring activities where the total time to perform a fixed number of executions is important, such as a countdown timer that ticks once every second for ten seconds. Finally, fixed-rate execution is appropriate for scheduling multiple repeating timer tasks that must remain synchronized with respect to one another.

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

Parameters:

参数:

  • task - task to be scheduled.
  • 任务-任务计划。
  • delay - delay in milliseconds before task is to be executed.
  • 延迟——任务执行前的毫秒延迟。
  • period - time in milliseconds between successive task executions.
  • 周期-连续任务执行之间的毫秒数。

Throws:

抛出:

  • IllegalArgumentException - if delay is negative, or delay + System.currentTimeMillis() is negative.
  • IllegalArgumentException—如果延迟为负,或delay + System.currentTimeMillis()为负。
  • IllegalStateException - if task was already scheduled or cancelled, timer was cancelled, or timer thread terminated.
  • IllegalStateException—如果任务已经被调度或取消,则会取消计时器或终止计时器线程。

#2


67  

ScheduledExecutorService

I wish to offer you an alternative to Timer using - ScheduledThreadPoolExecutor, an implementation of the ScheduledExecutorService interface. It has some advantages over the Timer class (from "Java in Concurrency"):

我希望向您提供一个使用ScheduledThreadPoolExecutor的计时器替代方法,它是ScheduledExecutorService接口的实现。它与定时器类(从“Java并发”)相比有一些优势:

A Timer creates only a single thread for executing timer tasks. If a timer task takes too long to run, the timing accuracy of other TimerTasks can suffer. If a recurring TimerTask is scheduled to run every 10 ms and another Timer-Task takes 40 ms to run, the recurring task either (depending on whether it was scheduled at fixed rate or fixed delay) gets called four times in rapid succession after the long-running task completes, or "misses" four invocations completely. Scheduled thread pools address this limitation by letting you provide multiple threads for executing deferred and periodic tasks.

计时器仅为执行计时器任务创建一个线程。如果一个计时器任务运行的时间太长,那么其他计时器任务的计时精度就会受到影响。如果反复出现的TimerTask调度运行每10和另一个女士Timer-Task花40 ms,要么重复任务(取决于是否安排在固定利率或固定延迟)在快速连续四次被调用长时间运行的任务完成后,或者完全“错过”四个调用。计划的线程池通过允许您为执行延迟任务和周期任务提供多个线程来解决这个限制。

Another problem with Timer is that it behaves poorly if a TimerTask throws an unchecked exception. The Timer thread doesn't catch the exception, so an unchecked exception thrown from a TimerTask terminates the timer thread. Timer also doesn't resurrect the thread in this situation; instead, it erroneously assumes the entire Timer was cancelled. In this case, TimerTasks that are already scheduled but not yet executed are never run, and new tasks cannot be scheduled. (This problem, called "thread leakage").

Timer的另一个问题是,如果TimerTask抛出一个未检查的异常,那么它的行为会很糟糕。计时器线程不会捕获异常,因此从TimerTask抛出的未检查异常将终止计时器线程。Timer在这种情况下也不会恢复线程;相反,它错误地假设整个计时器被取消。在这种情况下,已经调度但尚未执行的TimerTasks将永远不会运行,新的任务将无法调度。(这个问题叫做“漏线”)

And another recommendation if you need to build your own scheduling service, you may still be able to take advantage of the library by using a DelayQueue, a BlockingQueue implementation that provides the scheduling functionality of ScheduledThreadPoolExecutor. A DelayQueue manages a collection of Delayed objects. A Delayed has a delay time associated with it: DelayQueue lets you take an element only if its delay has expired. Objects are returned from a DelayQueue ordered by the time associated with their delay.

另外,如果需要构建自己的调度服务,还可以使用DelayQueue,这是一个block queue实现,它提供ScheduledThreadPoolExecutor的调度功能。DelayQueue管理延迟对象的集合。延迟具有与之相关的延迟时间:DelayQueue允许您仅在元素的延迟已过期时才获取元素。对象从与延迟相关联的时间排序的DelayQueue返回。

#3


13  

public void schedule(TimerTask task,long delay)

Schedules the specified task for execution after the specified delay.

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

you want:

你想要的:

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

Schedules the specified task for repeated fixed-delay execution, beginning after the specified delay. Subsequent executions take place at approximately regular intervals separated by the specified period.

将指定的任务安排为重复的固定延迟执行,从指定的延迟开始。随后的执行以大约有规律的间隔进行,间隔由指定的周期分隔。

#4


4  

You can use Quartz

您可以使用石英

#5


4  

Quartz scheduler is also a solution and firstly you make Quartz Job class.

Quartz调度器也是一种解决方案,首先创建Quartz作业类。

Quartz job is defined what you want to run

Quartz job定义了您想要运行的内容。

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);
        }
}

Now you need to make Quartz Trigger

现在你需要做石英触发器

There are two types of triggers in Quartz

Quartz有两种类型的触发器

SimpleTrigger – Allows to set start time, end time, repeat interval.

SimpleTrigger—允许设置开始时间、结束时间、重复间隔。

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

CronTrigger – Allows Unix cron expression to specify the dates and times to run your job.

CronTrigger——允许Unix cron表达式指定运行作业的日期和时间。

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

Scheduler class links both Job and Trigger together and execute it.

Scheduler类将作业和触发器链接在一起并执行它。

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

Full Example you can see here

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

#6


2  

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

计时器。scheduleAtFixedRate(新任务()、1000、3000);

#7


1  

For this purpose Java has Timer and TimerTask class but what is it ?

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

  • java.util.Timer is a utility class that can be used to schedule a thread to be executed at certain time in future. Java Timer class can be used to schedule a task to be run one-time or to be run at regular intervals.
  • java.util。Timer是一个实用程序类,可以用来调度将来某个时间要执行的线程。Java Timer类可用于调度一次运行或定期运行的任务。
  • java.util.TimerTask is an abstract class that implements Runnable interface and we need to extend this class to create our own TimerTask that can be scheduled using java Timer class.
  • java.util。TimerTask是一个实现Runnable接口的抽象类,我们需要扩展这个类来创建我们自己的TimerTask,它可以使用java Timer类进行调度。

You can check full tutorial from GeekonJava

您可以查看GeekonJava的完整教程

TimerTask timerTask = new MyTimerTask();

//running timer task as daemon thread

Timer timer = new Timer(true);

timer.scheduleAtFixedRate(timerTask, 0, 10*1000);