M S*_*ach 8 java multithreading timer timertask
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.
Run Code Online (Sandbox Code Playgroud)
我对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.
Run Code Online (Sandbox Code Playgroud)
我的期望scheduleAtFixedRate()方法(根据我在javadocs中给出的理解,其中每个执行是相对于初始执行的预定执行时间安排的)大约17个线程(不要太注意17.它可能或多或少.)但是它应该大于2)应该在第1行之后创建.
其中一个timer 应该产生16个其他线程,每个任务对应两个.首先任务休眠100秒,Timer应该创建对应于下一个任务的另一个线程,并且类似于其他任务.但是在调试点,我只看到一个对应的线程Timer.在这里我也可以看到任务的顺序执行.为什么不是17个线程?
更新: - 根据ScheduleAtFixedRate javadocs,each execution is scheduled relative to the scheduled execution time of the initial execution. If an execution is delayed for any reason (such as garbage collection or other background activity), two or more executions will occur in rapid succession to "catch up. what does that mean?对我来说它给人的印象是,如果第二个任务到期,即使第一个任务没有完成,那么计时器将为正当任务创建新线程.不是吗?
Timer在幕后使用活动对象模式,因此只有一个线程正在使用,并且在计时器上调度新任务会将该任务添加到线程的任务队列中。
计时器线程跟踪其队列中的所有任务并休眠,直到安排下一个任务。然后,它通过task.run()直接调用唤醒并执行任务本身,这意味着它不会产生另一个线程来执行代码。
这也意味着,如果您安排两个任务同时执行,则符合主动对象模式,它们将在同一控制线程上按顺序(一个接一个)执行。这意味着第二个任务将在预定时间之后执行(但可能不会太多)。
现在,为了明确回答您的问题,这里是调度逻辑,该调度逻辑Timer.class会在下次再次运行任务时进行调度(来自此处的第 262-272 行):
// 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);
Run Code Online (Sandbox Code Playgroud)
task.fixedRate如果使用其中一种timer.scheduleAtFixedRate()方法,则设置为 true,如果使用其中一种方法,则设置为 false timer.schedule()。
task.when 是任务计划运行的“时间”(滴答声)。
task.period是您传递给timer.schedule*()方法的间隔。
因此,从代码中我们可以看到,如果您使用固定速率,那么将安排重复任务相对于首次启动时运行。如果您不使用固定速率,那么它会被安排相对于上次运行的时间运行(这将相对于固定速率漂移,除非您的任务从不延迟并且执行时间少于 1 个刻度)。
这也意味着如果一个任务落后并且它的速率是固定的,那么Timer它将继续重新调度任务以立即执行,直到它赶上它应该在给定时间段内运行的总次数。
所以,如果你有一个任务,说ping()您计划以固定速度每10ms运行,并有暂堵在ping()方法到需要20ms的执行,那么Timer将调用ping()再次紧接在上通话结束后,它将继续这样做,直到达到给定的速率。
javadoc说Timer
与每个 Timer 对象对应的是一个单独的后台线程,用于顺序执行所有计时器的任务。
基本上,它保存一个任务队列,当您安排任务时它会添加到该队列中。它使用一个线程来迭代队列并执行任务。
| 归档时间: |
|
| 查看次数: |
19533 次 |
| 最近记录: |