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.
根据我理解 javadocs
中的描述,schedule()
方法应该满足每次执行都在前一个任务完成后进行调度的要求,因此我期望在第一行代码执行后会创建两个线程。
其中一个线程用于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.
根据我在JavaDocs中的理解,scheduleAtFixedRate()
方法的期望是每次执行都相对于初始执行时间进行调度。在第一行之后应该创建大约17个线程(不必过于关注17,它可能比这多或少,但应该大于2)。
其中一个线程为timer
,它应该会生成16个其他线程来对应每个任务的两个线程。首先,任务将休眠100秒,Timer
应该会为下一个任务创建另一个线程,以此类推。但是在调试点上,我只看到了一个与Timer
相关的线程。这里也可以看到任务的顺序执行。为什么没有17个线程呢?
更新:根据ScheduleAtFixedRate javadocs的说明,每个执行都是相对于初始执行时间进行调度的。如果由于任何原因(例如垃圾收集或其他后台活动)导致执行延迟,那么将会出现两个或更多次执行以“赶上”尚未完成的执行。那是什么意思?
对我来说,这给了我这样的印象:如果第二个任务到期,即使第一个任务尚未完成,定时器也会为到期任务创建新线程。是不是这样?
schedule
是固定延迟,而scheduleatFixedRate
是固定速率。这会影响计划任务运行的时间。 - Sotirios DelimanolisTimer
线程外,没有其他线程。任务在队列中。如果存在延迟,则在执行之间等待的时间将更短。 - Sotirios Delimanolis