我有以下代码段,使用ScheduledExecutorService
每3'000毫秒运行一次,检查是否应该调用函数onOutTimeout()
。至少这是个主意。
private void launchOutTimeoutChecker(){
Runnable check = new Runnable() {
@Override
public void run() {
float bonus = 0;
if(firstOutTime){bonus = timeout_initial_bonus;}
float temp = System.currentTimeMillis() - lastOutTime;
if(temp < timeout + bonus){
if(Debug.logKeepalivePackets){
Log.d("keepalive", "firstOutTime: "+firstOutTime+"\ntime passed: "+temp);
}
// don't timeout yet, launch new execution
launchOutTimeoutChecker(); // yey recursion?!
} else {
if(Debug.logKeepalivePackets){
Log.d("keepalive", "TIMEOUT!\nfirstOutTime: "+firstOutTime+"\ntime passed: "+temp);
}
onOutTimeout();
}
}
};
// before the first message, give a bonus of timeout_initial_bonus
long bonus = 0;
if(firstOutTime){bonus = timeout_initial_bonus;}
long time_out = bonus + timeout;
futureOut = executorOut.schedule(check, time_out, TimeUnit.MILLISECONDS);
// the task is now scheduled. after the timeout will it check whether it should actually trigger a timeout.
// the ScheduledFuture could be used to cancel this again
}
编辑:我设置lastOutTime
的位置在我的(runnable)类的run方法中。方法lastInTimeoutChecker
不会打印任何内容。
@Override
public void run() {
// initialize executors that are used in launchOutTimeoutChecker and launchInTimeoutChecker
executorIn = Executors.newSingleThreadScheduledExecutor();
executorOut = Executors.newSingleThreadScheduledExecutor();
// start the timers in new threads
this.lastOutTime = System.currentTimeMillis();
launchOutTimeoutChecker();
this.lastInTime = System.currentTimeMillis();
launchInTimeoutChecker();
}
我希望每3秒钟看一条日志消息,因为timeout
设置为3,实际上日志消息大约每3秒发生一次。 但是为什么这个输出说过的时间是0.0?
12-03 20:16:51.049 19578-19658/ch.ethz.inf.vs.a4.minker.einz D/keepalive: firstOutTime: false
time passed: 0.0
12-03 20:16:54.051 19578-19658/ch.ethz.inf.vs.a4.minker.einz D/keepalive: firstOutTime: false
time passed: 0.0
12-03 20:16:57.052 19578-19658/ch.ethz.inf.vs.a4.minker.einz D/keepalive: firstOutTime: false
time passed: 0.0
12-03 20:17:00.054 19578-19658/ch.ethz.inf.vs.a4.minker.einz D/keepalive: firstOutTime: false
time passed: 0.0
12-03 20:17:03.055 19578-19658/ch.ethz.inf.vs.a4.minker.einz D/keepalive: firstOutTime: false
time passed: 0.0
12-03 20:17:06.056 19578-19658/ch.ethz.inf.vs.a4.minker.einz D/keepalive: firstOutTime: false
time passed: 0.0
12-03 20:17:09.057 19578-19658/ch.ethz.inf.vs.a4.minker.einz D/keepalive: firstOutTime: false
time passed: 0.0
12-03 20:17:12.058 19578-19658/ch.ethz.inf.vs.a4.minker.einz D/keepalive: firstOutTime: false
time passed: 0.0
12-03 20:17:15.059 19578-19658/ch.ethz.inf.vs.a4.minker.einz D/keepalive: firstOutTime: false
time passed: 0.0
12-03 20:17:18.060 19578-19658/ch.ethz.inf.vs.a4.minker.einz D/keepalive: firstOutTime: false
time passed: 0.0
12-03 20:17:21.061 19578-19658/ch.ethz.inf.vs.a4.minker.einz D/keepalive: firstOutTime: false
time passed: 0.0
12-03 20:17:24.062 19578-19658/ch.ethz.inf.vs.a4.minker.einz D/keepalive: firstOutTime: false
time passed: 0.0
12-03 20:17:27.064 19578-19658/ch.ethz.inf.vs.a4.minker.einz D/keepalive: firstOutTime: false
time passed: 0.0
12-03 20:17:30.067 19578-19658/ch.ethz.inf.vs.a4.minker.einz D/keepalive: firstOutTime: false
time passed: 0.0
12-03 20:17:33.068 19578-19658/ch.ethz.inf.vs.a4.minker.einz D/keepalive: firstOutTime: false
time passed: 0.0
12-03 20:17:36.071 19578-19658/ch.ethz.inf.vs.a4.minker.einz D/keepalive: firstOutTime: false
time passed: 0.0
12-03 20:17:39.072 19578-19658/ch.ethz.inf.vs.a4.minker.einz D/keepalive: firstOutTime: false
time passed: 0.0
12-03 20:17:42.074 19578-19658/ch.ethz.inf.vs.a4.minker.einz D/keepalive: firstOutTime: false
time passed: 0.0
12-03 20:17:45.076 19578-19658/ch.ethz.inf.vs.a4.minker.einz D/keepalive: TIMEOUT!
firstOutTime: false
time passed: 131072.0
大约一分钟后,终于出现超时消息,我原本期望将其作为第一条日志消息。通过它的时间表示始终完全 131072
毫秒。
我根本不明白如何调试这个。我做了什么:
确保只有一个周围类的实例正在运行。没有太大的改变(除了你现在看到的输出,而不是每个重复的消息,但其他一切都是相同的)
确保lastOutTime
仅设置一次,在第一次致电launchOutTimeoutChecker()
之前,将其设置为System.currentTimeMillis()
firstOutTime目前始终为false,因此该部分应无关紧要
起初,它按预期工作。然后我在调试模式下运行相同的代码,这发生了。现在按下常规运行时也会出现上述输出。
重建没有解决它
在真实设备而非模拟器上运行它会表现出相同的行为。
CPU使用率或内存使用率似乎没有显着变化
我的代码出了什么问题?
答案 0 :(得分:1)
如果我理解了您的要求,您希望安排一个任务,该任务将以固定费率检查某些条件,以了解您是否应该调用名为onOutTimeout
的某个函数。以下是此要求的简单解决方案:
private long timeWhenYouShouldCallYourFunction;
private ScheduledExecutorService service;
private void launchOutTimeoutChecker() {
Runnable check = new Runnable() {
@Override
public void run() {
long currentTime = System.currentTimeMillis();
System.out.println("ping " + currentTime);
if (currentTime > timeWhenYouShouldCallYourFunction) {
onOutTimeout();
service.shutdown();
}
}
};
int randomShift = Math.abs(new Random().nextInt() % 10_000);
System.out.println("Shift is " + randomShift + " msec");
timeWhenYouShouldCallYourFunction = System.currentTimeMillis() + randomShift;
service = Executors.newSingleThreadScheduledExecutor();
service.scheduleAtFixedRate(check, 0, 3000, TimeUnit.MILLISECONDS);
}
private void onOutTimeout() {
System.out.println("Made it!");
}
答案 1 :(得分:1)
尽量不要使用float
毫秒。 System.currentTimeMillis()
会返回long
,这可能会给您带来麻烦。