我正在尝试使用一些代码来实现计划任务,并提出了这些代码。
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分钟后,我只得到一个输出......我该如何解决这个问题?
答案 0 :(得分:74)
ScheduledExecutorService
超过Timer
我希望为您提供Timer
使用 - ScheduledThreadPoolExecutor的替代方案,ScheduledExecutorService接口的实现。根据“Java in Concurrency”:
Timer
只创建一个用于执行计时器任务的线程。如果一个 定时器任务运行时间太长,其他的定时精度TimerTask
会受到影响。如果计划重复运行TimerTask
每隔10毫秒,另一个Timer-Task需要40毫秒才能运行,反复出现 任务(取决于它是按固定费率安排还是 固定延迟)之后快速连续四次被调用 长时间运行的任务完成,或完全“错过”四个调用。 计划的线程池通过允许您提供来解决此限制 用于执行延迟和定期任务的多个线程。
Timer的另一个问题是,如果TimerTask
引发未经检查的异常,则表现不佳。另外,称为“线程泄漏”
Timer线程没有捕获异常,因此未经检查 从
TimerTask
抛出的异常终止计时器线程。计时器 在这种情况下也不会复活线程;相反,它 错误地假设整个计时器被取消。在这种情况下, 从未调度但尚未执行的TimerTasks 运行,无法安排新任务。
另外一条建议是,如果您需要构建自己的调度服务,您仍然可以使用DelayQueue
,BlockingQueue
实现来提供{的调度功能,从而利用该库。 {1}}。 ScheduledThreadPoolExecutor
管理一组Delayed对象。延迟具有与之关联的延迟时间:DelayQueue
允许您仅在其延迟已过期时获取元素。对象按照与其延迟相关联的时间排序的DelayQueue
返回。
答案 1 :(得分:67)
public void scheduleAtFixedRate(TimerTask task,
long delay,
long period)
在指定的延迟之后开始,为重复的固定速率执行计划指定的任务。随后的执行大约定期进行,并按指定的时间段分开 在固定速率执行中,每次执行都是相对于初始执行的预定执行时间进行调度的。如果由于任何原因(例如垃圾收集或其他后台活动)延迟执行,则会快速连续执行两次或更多次执行以“赶上”。从长远来看,执行频率将恰好是指定周期的倒数(假设Object.wait(long)下的系统时钟是准确的)。
固定费率执行适用于对绝对时间敏感的重复活动,例如每小时按小时响铃,或在特定时间每天运行定期维护。它也适用于重复活动,其中执行固定执行次数的总时间很重要,例如倒计时器,每秒钟滴答一次,持续十秒钟。最后,固定速率执行适用于调度必须保持彼此同步的多个重复计时器任务。
参数:
抛出:
答案 2 :(得分:14)
public void schedule(TimerTask task,long delay)
在指定的延迟后安排指定的任务执行。
你想要:
public void schedule(TimerTask task, long delay, long period)
在指定的延迟之后开始,为重复的固定延迟执行计划指定的任务。随后的执行大约以规定的时间间隔进行,并按指定的时间段分开。
答案 3 :(得分:4)
Quartz调度程序也是一个解决方案,首先你可以创建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中有两种类型的触发器
SimpleTrigger - 允许设置开始时间,结束时间,重复间隔。
Trigger trigger = newTrigger().withIdentity("TriggerName", "Group1")
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(10).repeatForever()).build();
CronTrigger - 允许Unix cron表达式指定日期和 时间来完成你的工作。
Trigger trigger = newTrigger()
.withIdentity("TriggerName", "Group2")
.withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ?")).build();
计划程序类将作业和触发器链接在一起并执行它。
Scheduler scheduler = new StdSchedulerFactory().getScheduler();
scheduler.start();
scheduler.scheduleJob(job, trigger);
答案 4 :(得分:2)
timer.scheduleAtFixedRate( new Task(), 1000,3000);
答案 5 :(得分:1)
为此,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);