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
中给出的理解,其中每次执行都是在前一个任务执行完成后安排的)应该在第1行之后创建两个线程。
一个用于计时器,它为任务生成另一个线程。一旦第一个任务线程死亡,将创建另一个任务线程并继续执行。但在调试点,我只看到一个线程对应于计时器。为什么不为实现可运行的任务执行线程?
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行之后创建。
一个用于计时器,它应该产生16个其他线程,每个任务对应两个线程。在第一个任务Hibernate100秒时,计时器应该创建另一个对应于下一个任务的线程,同样也应该为其他任务创建另一个线程。但在调试点,我只看到一个线程对应于计时器。在这里,我还可以看到任务的顺序执行。为什么不是17个线程?
更新:-根据ScheduleAtFixedRate javadocs,每个执行都是相对于初始执行的计划执行时间进行调度的。如果执行因任何原因(如垃圾收集或其他后台活动)而延迟,两个或多个执行将快速连续发生,以“追赶”。这意味着什么?对我来说,这给人的印象是,如果第二个任务到期,即使第一个任务未完成,计时器也会为到期的任务创建新线程。不是吗?
计时器类为计时器类的每个实例创建一个线程,该线程执行所有任务调度计时器#调度或计时器#调度AtFixATE。
因此,正如您所知道的,计时器只创建一个线程。
任务将在精确任务完成之前到达开始时间,然后接下来的任务一直等到精确任务完成。
因此,计时器“永远不会”创建另一个线程,尽管精确任务还没有完成,并且接下来的任务必须开始的时间已经到来。
因此,我建议您:
如果您想安排任务并按时完成任务,无论任务是否完成,请使用ScheduledThreadPoolExecutor而不是计时器。
虽然如果你不想,它更喜欢使用schduledThreadPoolExector比定时器,因为一方面,如果任务会抛出RuntimeException或Error,定时器调度的任务永远不会完成。
Timer
的javadoc说
与每个计时器对象相对应的是一个后台线程,用于按顺序执行计时器的所有任务。
基本上,它包含了一个任务队列,当你安排任务时,它会将任务添加到队列中。它使用一个线程在队列上迭代并执行任务。
计时器使用引擎盖下的活动对象模式,因此只使用单个线程,在计时器上调度新任务会将该任务添加到线程的任务队列中。
计时器线程跟踪其队列中的所有任务并Hibernate,直到调度下一个任务。然后,它唤醒并通过直接调用
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);
任务。如果使用其中一个计时器,则fixedRate将设置为true。scheduleAtFixedRate()
方法,如果使用其中一个计时器,则设置为false。schedule()方法。
任务。when是任务计划运行的“时间”(滴答声)。
task.period
是传递给timer.schedule*()
方法的间隔。
因此,从代码中我们可以看到,如果您使用固定速率,那么重复任务将被安排相对于它第一次启动时运行。如果您不使用固定速率,那么它将被安排相对于上次运行时运行(这将相对于固定速率漂移,除非您的任务从未延迟并且执行时间少于一个刻度)。
这也意味着,如果任务落后并且处于固定速率,则计时器将继续重新调度任务以立即执行,直到它赶上在给定时间段内应运行的总次数。
因此,如果您有一个任务,比如一个计划每10ms以固定速率运行的ping()
,并且在ping()
方法中存在临时阻塞,需要20ms才能执行,那么计时器将在前一个调用完成后立即再次调用
ping()
,并且它将继续这样做,直到达到给定的速率。
我正在编写一个Android应用程序,每10分钟录制一次音频。我用定时器来做这件事。但是scheduleAtFixedRate和scheduleAtFixedRate之间有什么区别呢?使用其中一种方法是否有性能优势?
关于Java定时器类或ScheduledExecutorService接口,我可以在执行器线程(其他调度器)的运行方法(或TimerTask)内设置调度器(或定时器)吗? 案例研究:我有一个数据库,其中包含歌曲列表(10000首)和播放歌曲的时间表。 所以我想创建一个调度程序(比如1)(周期为1小时),它将搜索数据库,并为计划在一小时内播放的所有歌曲创建调度程序。 一小时后,scheduler1将
问题内容: 我已经阅读了几次此页面,只是没有看到GWT 和类之间的某些固有差异。我正在寻找以下各项的用例和适用性: ,和 这些似乎或多或少都在做着相同的事情,感觉您可以使用所有这些东西实现相同的目标。这仅仅是GWT的一种方式,提供了多种完成同一件事的方式吗?如果没有,请帮助我了解何时何地适当使用它们。 问题答案: 如果需要浏览器完成当前正在执行的操作,然后再告诉它执行其他操作,请使用 Schedu
问题内容: 我已将一个WAR文件部署到Tomcat服务器,该类之一将在启动时调用,然后init()方法将安排一个计时器,每5小时触发一次以执行一些任务。 我的init()代码如下所示: 我的应用程序运行没有问题,但是当我使用 /etc/init.d/tomcat7 stop 关闭Tomcat时,我检查了日志(catalina.out),它具有以下条目: 严重:Web应用程序[/ MyApplica
我正在建立一个Android应用程序,必须定期做一些服务。我发现使用< code > ScheduledThreadPoolExecutor 和< code > ScheduledExecutorService 比< code>Timer更好。 有人能解释一下和的区别吗?哪款更适合Android? 更新 我刚刚发现这篇文章和这篇文章解释了实现重复周期性任务的几种方法之间的区别。在我的情况下,和更合
本文向大家介绍JavaScript setInterval()与setTimeout()计时器,包括了JavaScript setInterval()与setTimeout()计时器的使用技巧和注意事项,需要的朋友参考一下 JavaScript是单线程语言,但是它可以通过设置超时值和间歇时间值来指定代码在特定的时刻执行。超时值是指在指定时间之后执行代码,间歇时间值是指每隔指定的时间就执行一次代