当前位置: 首页 > 知识库问答 >
问题:

计划和时间表的区别是什么?

樊博雅
2023-03-14

Timer类的这两种方法之间有什么区别:

schedule(TimerTask task, long delay, long period)

scheduleAtFixedRate(TimerTask task, long delay, long period)

文档并不能清楚地区分它们之间的区别。

共有2个答案

太叔逸春
2023-03-14

谢谢@Nizet的回答,我已经为一些想练习和学习的人编写了一个示例代码。

import java.util.Timer;
import java.util.TimerTask;

public class TimerTest {

    public static void main(String args[]){
        TimerTest.DelayTask task = new DelayTask();
        Timer timer = new Timer();
        /**
         * Use schedule or scheduletAtFixedrate and check the printed result
         */
        timer.schedule(task, 0, 5000);
        //timer.scheduleAtFixedRate(task, 0, 5000);
    }

    public static boolean stop = false;

    public static void delayOneSec(String status){
        try{
            System.out.print(status);
            Thread.sleep(1000);
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    static class DelayTask extends TimerTask{
        int count = 2;

        @Override
        public void run() {
            // TODO Auto-generated method stub
            stop = true;
            for(int i = 0; i < count; i++){
                TimerTest.delayOneSec("T");
            }
            if(count == 2){
                count = 6;
            }else{
                count = 2;
            }
            stop = false;
            new PrintW().start();
        }
    }

    static class PrintW extends Thread{
        @Override
        public void run(){
            while(!stop){
                TimerTest.delayOneSec("W");
            }
        }

    }
}

任务本身将重复2秒或6秒。让我们看看每个场景的结果。

使用计时器时。进度表(任务,0,5000) ,输出为TTWWWTTTTTTTTWWWTTTTTTTTTTWWWTTTTTTTTTT。如您所见,计时器遵循如下规则,如果任务按时完成,则等待到时段超时,如果当前任务持续时间超过时段,则立即启动下一个任务。

当使用timer.scheduleAtFixed速率(任务,0,5000);时,输出为TTWWTTTTTTTWWTTTTTTWWTTTTTWWTTTTTWWTTTTTTWWTTTTTTTTTTTTWWTTTTTTWWTTTTTTTTT。现在情况有点不同了。javadoc

两次或两次以上的处决将迅速接踵而至,以“迎头赶上”

在这里生效。如您所见,忽略第一个TTWW,每两个任务将打印TTTTTTWW,持续10秒(两个周期)。

让我们深入研究一下定时器的源代码。

public void schedule(TimerTask task, Date firstTime, long period) {
    if (period <= 0)
        throw new IllegalArgumentException("Non-positive period.");
    sched(task, firstTime.getTime(), -period);
}


public void scheduleAtFixedRate(TimerTask task, long delay, long period) {
    if (delay < 0)
        throw new IllegalArgumentException("Negative delay.");
    if (period <= 0)
        throw new IllegalArgumentException("Non-positive period.");
    sched(task, System.currentTimeMillis()+delay, period);
}

如您所见,在调度方法中,周期被转移到负值。来看看排期的时候有什么区别。

以下代码位于timerReadmain循环中,

currentTime = System.currentTimeMillis();
executionTime = task.nextExecutionTime;
if (taskFired = (executionTime<=currentTime)) {
    if (task.period == 0) { // Non-repeating, remove
        queue.removeMin();
        task.state = TimerTask.EXECUTED;
    } else { // Repeating task, reschedule
        queue.rescheduleMin(
        task.period<0 ? currentTime   - task.period
                      : executionTime + task.period);
           }
    }
}

这就是神奇发生的地方,对于schedule方法,下一个任务执行时间基于currentTime,该时间是在该任务运行之前计算的。也就是说,每个任务的执行时间只与前一个任务的开始时间相关。

任飞龙
2023-03-14

文档确实解释了差异:

附表:

在固定延迟执行中,每次执行都是相对于前一次执行的实际执行时间进行调度的。如果执行因任何原因(如垃圾收集或其他后台活动)而延迟,则后续执行也将延迟。

因此,假设延迟为5秒,每个任务需要2秒,那么

TTWWWTTWWWTTWWWTT

其中T表示任务执行的1秒,而W表示等待1秒。

但是现在假设一个长GC(由G表示)发生并延迟了第二个任务,第三个任务将在第二个任务开始后5秒开始,就好像长GC没有发生一样:

TTWWWGGTTWWWTTWWWTT

第三个任务在第二个任务后5秒开始。

时间表固定日期:

在固定速率执行中,每个执行都是相对于初始执行的计划执行时间进行计划的。如果执行因任何原因(如垃圾收集或其他后台活动)而延迟,则两个或多个执行将快速连续发生以“赶上”。

因此,使用与上面相同的延迟和相同的GC,您将得到

TTWWWGGTTWTTWWWTT

第三个任务开始3秒,而不是第二个任务之后的5秒,以赶上进度。

 类似资料:
  • 本文向大家介绍长期计划程序和短期计划程序之间的区别。,包括了长期计划程序和短期计划程序之间的区别。的使用技巧和注意事项,需要的朋友参考一下 长期计划者 长期调度程序也称为JOB调度程序。它维护程序/作业的队列,这些队列被选择供系统处理。根据调度机制选择程序并进行处理。长期调度程序控制着多重编程的程度。 短期计划者 短期调度程序也称为CPU调度程序。它维护上下文切换,并且CPU在多个线程之间切换。短

  • 本文向大家介绍lodash和下划线之间有什么区别?,包括了lodash和下划线之间有什么区别?的使用技巧和注意事项,需要的朋友参考一下 lodash和underscore都是实用程序库,它们通过提供使数组,数字,对象,字符串等的使用更加容易的实用程序,使JavaScript变得更容易。这些库非常适合- 迭代数组,对象和字符串 操作和测试值 创建复合函数 它们都是功能库。Lo-Dash是Unders

  • 在Java 7之前,JVM内存中有一个名为PermGen的区域,JVM以前在这里保存它的类。在Java 8中,它被移除并被称为元空间的区域所取代。 PermGen和Metaspace之间最重要的区别是什么? 我知道的唯一区别是,并且忽略了VM参数。

  • 和之间有什么区别? 是什么原因导致他们被扔?如何解决这些问题? 在修改现有代码以包含新的jar文件时,我经常会遇到这些可抛物。我在通过WebStart发布的一个Java应用程序的客户端和服务器端都碰到了它们。 我遇到的可能原因是: 代码客户端的中未包含的包 我们正在使用的新JAR缺少运行时类路径 版本与以前的JAR冲突 当我今天遇到这些问题时,我会采取跟踪和错误的方法来使事情正常工作。我需要更多的

  • 当我试图在Spring4.x上进行测试时,我使用了MockMvc web客户端,但我正在阅读和尝试Spring5.x的新特性。 我认为,WebTestClient和MockMvc是相同或非常相似的。 MockMvc和WebTestClient之间的区别是什么?

  • 有人能给我解释一下map和flatMap之间的区别,以及什么是各自的好用例吗? “结果扁平化”是什么意思?它有什么好处?