gpt4 book ai didi

java - 计时器计划与 scheduleAtFixedRate?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:45:03 35 4
gpt4 key购买 nike

public class MyTimerTask extends TimerTask{

@Override
public void run() {
int i = 0;
try {
Thread.sleep(100000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Run Me ~" + ++i);
System.out.println("Test");

}

}

Case 1 :-
TimerTask task = new MyTimerTask();
Timer timer = new Timer();
timer.schedule(task, 1000,6000); // line 1
System.out.println("End"); // here is bebug point.

我对 schedule() 方法的期望(根据我在 javadocs 中给出的理解,其中每次执行都在上一个任务执行完成后安排)那两个线程应该是在第 1 行之后创建。

一个用于 timer,它为任务生成另一个线程。一旦第一个任务线程死亡另一个将被创建并继续下去。但是在调试点,我只看到一个线程对应于 Timer。为什么不是实现 Runnable 任务的线程?

Case 2 :-

TimerTask task = new MyTimerTask();
Timer timer = new Timer();
timer.scheduleAtFixedRate(task, 1000,6000); // line 1
System.out.println("End"); // here is bebug point.

我对 scheduleAtFixedRate() 方法的期望(根据我在 javadocs 中给出的理解,其中每个执行都是相对于计划的初始执​​行的执行时间)大约17个线程(不要太在意到 17。它可以或多或少到那个。但它应该大于 2 ) 应该是在第 1 行之后创建。

一个用于 timer,它应该产生 16 个其他线程,对应每个任务两个。起初任务 hibernate 对于 100 秒,Timer 应该创建另一个线程对应于下一个任务并且类似地用于其他任务。但是在调试点,我只看到一个线程对应于 Timer。在这里我也可以看到任务的顺序执行。为什么不是 17 个线程?

更新:- 根据ScheduleAtFixedRate javadocs , 每次执行都是相对于初始执行的调度执行时间进行调度的。如果执行因任何原因(例如垃圾收集或其他后台 Activity )而延迟,则将快速连续执行两次或更多次以“ catch 进度。那是什么意思?给我的印象是,如果第二次任务到期即使第一个任务没有完成,然后计时器会为到期任务创建新线程。不是吗?

最佳答案

Timer 使用 Active Object引擎盖下的模式,所以只有一个线程被使用,并且在计时器上调度一个新任务将该任务添加到线程的任务队列中。

计时器线程跟踪其队列中的所有任务并 hibernate 直到安排下一个任务。然后,它会唤醒并通过直接调用 task.run() 自行执行任务,这意味着它不会生成另一个线程来执行代码。

这也意味着,如果您安排两个任务同时执行,那么根据 Activity 对象模式,它们将在同一控制线程上按顺序(一个接一个)执行。这意味着第二个任务将在预定时间后执行(但可能不会太多)。

现在,为了明确回答您的问题,下面是 Timer.class 中的调度逻辑,它调度任务应该再次运行的下一次时间(来自第 262-272 行 here ):

// set when the next task should be launched
if (task.fixedRate) {
// task is scheduled at fixed rate
task.when = task.when + task.period;
} else {
// task is scheduled at fixed delay
task.when = System.currentTimeMillis()
+ task.period;
}

// insert this task into queue
insertTask(task);
如果您使用 timer.scheduleAtFixedRate() 方法之一,

task.fixedRate 设置为 true,如果您使用 方法之一,则设置为 false timer.schedule() 方法。

task.when 是任务计划运行的“时间”(滴答)。

task.period 是您传递给 timer.schedule*() 方法的间隔。

因此,从代码中我们可以看出,如果您使用固定速率,那么将安排重复任务相对于首次启动时运行。如果您不使用固定速率,那么它会相对于上次运行的时间安排运行(这将相对于固定速率漂移,除非您的任务永远不会延迟并且执行时间少于一个滴答)。

这也意味着,如果一个任务落后了,而且它是固定速率的,那么 Timer 会不断地重新安排任务以立即执行,直到它 catch 它应该有的总次数在给定的时间段内运行。

因此,如果您有一项任务,例如您计划每 10 毫秒以固定速率运行的 ping() 并且 ping() 中存在临时阻塞方法到需要 20 毫秒执行的地方,然后 Timer 将在上一次调用完成后立即再次调用 ping(),并且它将继续这样做,直到给定速率为实现了。

关于java - 计时器计划与 scheduleAtFixedRate?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20844735/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com