所以我和我的团队遇到了一个问题,我们认为调度程序没有正确处理。我们这里有一段代码取消了ScheduleFuture,然后创建了一个新代码。
public void restartEventTimer(long time) {
try {
if (disposed) {
return;
}
timeStarted = System.currentTimeMillis();
eventTime = time;
if (timeout != null) {
timeout.cancel(false);
}
timeout = null;
final int timesend = (int) time / 1000;
for (MapleCharacter chr : getPlayers()) {
chr.getClient().getSession().write(MaplePacketCreator.getClock(timesend));
}
timeOut(time);
} catch (Exception ex) {
LogHelper.INVOCABLE.get().info("restartEventTimer: Event name " + em.getName() + ", Instance name : " + name + " ", ex);
}
}
现在我的理解是,cancel不会处理计时器,而是在后端设置一个值isDone()设置为true。我想知道是否因为ScheduledThreadPoolExecutor没有运行代码来处理在后端修剪它。我应该为ScheduleFuture创建一个包装器并覆盖默认实现,以确保调用isDone(),它不会通过Runnable运行。
public boolean timeOut(final long delay) {
if (disposed || em == null) {
return false;
}
try {
timeout = TimerManager.getInstance().schedule(() -> {
if (disposed || em == null) {
return;
}
try {
em.getIv().invokeFunction("scheduledTimeOut", this);
} catch (Exception e) { //i know, it should be just NoSuchMethodException, but idc.
LogHelper.INVOCABLE.get().info("timeOut: Event name " + em.getName() + ", Instance name : " + name + " " + e);
}
}, delay);
} catch (NullPointerException e) {
// Null pointer arises when you dispose in the scheduledTimeOut method, thus making this particular event instance object null and making timeout throw a nullpointer
} catch (Exception e) {
LogHelper.INVOCABLE.get().info("timeOut: Event name " + em.getName() + ", Instance name : " + name + " " + e);
}
return true;
}
我们还确保将这些参数设置为执行者:
setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
setRemoveOnCancelPolicy(true);
setKeepAliveTime(15, TimeUnit.MINUTES);