- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
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/
我尝试每小时执行一次代码 这是针对applicationRunner中的java,可以在服务器启动时运行。 @Component public class TestApplicationRunner
我在程序中使用方法scheduleAtFixedRate(Timer类)。它每秒运行一次,但有时此方法变得非常快(每秒执行 3 - 4 次)。 但是我在网络上做了一些研究,发现了这个: 从 Andro
日志: [pool-1-thread-1] TRACE apns.ApnsPushConnection - 输入方法 queryFeedbackService 参数[pool-3-thread-1]
我正在阅读一本 java8 书籍,发现了 ScheduleAtFixedRate 和 ScheduledExecutorService 中的 scheduleWithFixedDelay 方法之间的区
我们需要通过 Java 程序关注 PC 时钟。为此,我们每 500 毫秒使用 ScheduleAtFixedRate() 调度一个 Runnable。我们每次都从中调用 System.currentT
我正在编写一个应用程序,它生成随机数并在 Android 屏幕上显示它们(一个接一个)。这是 Activity java fragment 。 public class Scada extends A
public class MyTimerTask extends TimerTask{ @Override public void run() { int i = 0;
我有一个 Java 应用程序,用于通过 UART 连接 (RS422) 与嵌入式设备通信。主机以 5 毫秒为间隔向微 Controller 查询数据。直到最近我一直在使用 ScheduledExecu
我有 TextView 来频繁更新时间,工作正常,但问题是我想根据不同的条件更改计划时间,但我无法更改计划时间。它继续在最初设置的时间。 private Long mPeriod = Long.par
我正在研究 Java 类 ScheduledExecutorService 的 scheduleAtFixedRate 方法。 这是我的可疑代码: ScheduledExecutorService s
import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import
我正在尝试使用 ScheduledExecutorService 类的方法 scheduleAtFixedRate 进行示例。代码是: ScheduledExecutorService service
我创建了一个可运行的类并创建了一个线程,但具有唯一的名称,但是当我通过 executor.scheduleAtFixedRate 发送该线程时,它创建了自己的线程,我不明白这是为什么? 我试着阅读这里
当我定期执行一项耗时的任务时,结果没有达到我的预期。 public static void main(String[] args) { ScheduledExecutorService sch
我正在使用ScheduledExecutorService使用 scheduleAtFixedRate 方法每小时提供一次数据库更新。问题是它逐渐变得更晚 - 在长期服务中我一直在记录它并且每天大约一
这是我的固定速率计时器代码。当 Activity 进入 onPause(); 时,我可以暂停这个计时器吗?如果是这样,那么您建议我在 onPause(); 方法中放入什么,当应用程序进入 onResu
Runnable runPickWinner = new Runnable() { @Override public void run() {
因为我每秒都在执行时间紧迫的任务,所以我比较了几种方法以找到确保我的任务真正以固定时间步长执行的最佳方法。在计算所有方法的误差标准推导后,似乎使用方法 scheduledExecutorService
final Runnable refresh = new Refresh(params...); service = Executors.newScheduledThreadPool(1); serv
我的代码是: ou=100 final Timer t=new Timer(); TimerTask tt=new TimerTask() { @Overrid
我是一名优秀的程序员,十分优秀!