Java 如何安排任务定期运行?
我尝试了一些代码来实现一个预定的任务,并想出了这些代码Java 如何安排任务定期运行?,java,timer,schedule,Java,Timer,Schedule,我尝试了一些代码来实现一个预定的任务,并想出了这些代码 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
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分钟,我只得到一个输出…我如何解决这个问题
public void schedule(TimerTask task,long delay)
计划在指定的延迟后执行指定的任务
你想要:
public void schedule(TimerTask task, long delay, long period)
将指定的任务安排为重复固定延迟执行,从指定延迟后开始。随后的执行大约以指定的时间间隔定期进行。使用
将指定的任务安排为重复的固定速率执行,从指定的延迟后开始。随后的执行以大约固定的间隔进行,间隔为指定的时间段。在固定速率执行中,每个执行都是相对于初始执行的计划执行时间进行计划的。如果执行因任何原因(如垃圾收集或其他后台活动)而延迟,则两个或多个执行将快速连续发生以“赶上”。从长远来看,执行频率将正好是指定周期的倒数(假设系统时钟底层对象。wait(long)是准确的) 固定速率执行适用于对绝对时间敏感的重复活动,例如每小时按一次钟声,或每天在特定时间运行计划维护。它也适用于执行固定执行次数的总时间很重要的重复活动,例如倒数计时器,它每秒滴答一次,持续10秒。最后,固定速率执行适用于调度多个重复计时器任务,这些任务必须彼此保持同步 参数:
- 任务-要计划的任务
- 延迟-执行任务前的延迟(毫秒)
- period—连续执行任务之间的时间(以毫秒为单位)李>
- IllegalArgumentException-如果延迟为负,或延迟+System.currentTimeMillis()为负李>
- IllegalStateException-如果任务已计划或取消,则计时器已取消,或计时器线程已终止
ScheduledExecutorService
优于定时器的优点
我希望为您提供一种替代定时器
的方法,使用-,实现接口。根据“Java in Concurrency”,它比Timer类有一些优势:
计时器
只创建一个用于执行计时器任务的线程。如果
计时器任务运行时间太长,影响其他任务的计时精度
TimerTask
可能会受到影响。如果计划运行定期的TimerTask
每10毫秒和另一个计时器任务运行40毫秒,循环
任务(取决于它是按固定速率还是按
固定延迟)在
长时间运行的任务完成,或完全“错过”四次调用。
计划线程池通过允许您提供
用于执行延迟和定期任务的多个线程
计时器的另一个问题是,如果TimerTask
抛出未经检查的异常,则计时器的性能会很差。也称为“螺纹泄漏”
计时器线程没有捕获异常,因此未选中
从TimerTask
引发的异常终止计时器线程。计时器
在这种情况下也不会复活线程;相反,它
错误地认为整个计时器已取消。在这种情况下,,
已计划但尚未执行的TimerTask永远不会
运行,则无法计划新任务
另一个建议是,如果您需要构建自己的调度服务,您仍然可以通过使用DelayQueue
,一种BlockingQueue
实现来利用该库,该实现提供了ScheduledThreadPoolExecutor
的调度功能。DelayQueue
管理延迟对象的集合。延迟的元素有一个与之相关联的延迟时间:DelayQueue
允许您仅在其延迟已过期时获取元素。对象从DelayQueue
返回,该队列按与其延迟相关联的时间排序 scheduleAtFixedRate没有解决只获取一次输出的问题。@JamesA.N.Stauffer,他需要重复输出,而不是一次。是的,但重复只需添加第三个参数即可实现——不需要更改方法。@st0le。考虑下面的类比。提问者说“天是蓝的”,你说的是“不,草是绿的。”-如果他的问题是“什么是固定速率重复”,那么你的答案将是理想的。如果你希望它是某个上下限范围内的随机速率呢?计时器的另一个问题是改变系统时钟,它与timerQuartz调度程序发生冲突,帮助Java应用程序调度作业/任务,使其在指定的日期和时间运行,这些类已被替换为。有关详细信息,请参见JavaDoc上的第7段。
timer.scheduleAtFixedRate( new Task(), 1000,3000);
timer.scheduleAtFixedRate( new Task(), 1000,3000);