我对ScheduledThreadPoolExecutor
感到有疑问。
我需要一个超时,它会在'n'-seconds
之后重定向到第一页。如果用户输入一个字符,计时器应该再次开始计数,并且可能不会重定向到第一页。
(因此,计数器应该中止他的预定任务)
问题是,Timer启动了,但是如果键入了键,它不会取消计划的任务。将调用stop()
- 方法。但scheduledThreadPool.shutdownNow();
似乎不起作用。
我的TimerClass如下所示:
public class MyTimer {
private final Runnable logicalWorker;
private final long delay;
private final ScheduledThreadPoolExecutor scheduledThreadPool;
public MyTimer(final Runnable logicalWorker, final long delay) {
scheduledThreadPool = new ScheduledThreadPoolExecutor(1);
this.logicalWorker = logicalWorker;
this.delay = delay;
}
public void start() {
scheduledThreadPool.schedule(logicalWorker, delay, TimeUnit.SECONDS);
}
public void stop() {
scheduledThreadPool.shutdownNow();
scheduledThreadPool.getQueue().clear();
}
public void restart() {
start();
}
public boolean isScheduled() {
return !scheduledThreadPool.isTerminated() && !scheduledThreadPool.isShutdown();
}
}
调用timerClass的超类中的方法是这样的:
protected void startTimeout() {
if (currentInstance.getAutoTimeout() != null && currentInstance.getAutoTimeout().isScheduled()) {
currentInstance.getAutoTimeout().restart();
return;
}
currentInstance.setAutoTimeout(new MyTimer(new Runnable() {
@Override
public void run() {
Platform.runLater(new Runnable() {
@Override
public void run() {
if (!PageContent.PAGE_ID.equals(currentInstance.getPageId()) && !forceOpen) {
cancelCurrentProcesses();
switchPageByPageId(PageContent.PAGE_ID);
}
}
});
}
}, currentInstance.getPageDelay()));
if (currentInstance.getPageDelay() > 0) {
currentInstance.getAutoTimeout().start();
}
}
KeyListener和MouseClickListener将通过以下方法在场景中设置:
protected void placePage() throws SecurityException, IllegalArgumentException, IllegalAccessException,
InstantiationException, NoSuchMethodException, InvocationTargetException {
startTimeout();
currentInstance.getRoot().setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent arg0) {
startTimeout();
}
});
currentInstance.getRoot().setOnKeyReleased(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent arg0) {
startTimeout();
}
});
}
答案 0 :(得分:1)
看看这个 - &gt; http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html
shutdownNow()
不保证取消执行。
对于解决方案,我建议您使用ScheduledFuture
或Future
个对象,而不是Runnable
。
[编辑]预定的未来,您可以拨打.cancel()
功能而不是.shutdownNow()
来调用.schedule()
来电,但您似乎不会在任何地方使用(或确实保存)Future
的句柄。是的,您仍需要Runnable
,但只能提供Future
句柄。
尝试这样的事情:
private ScheduledFuture<?> future;
public void start() {
future = scheduledThreadPool.schedule(logicalWorker, delay, TimeUnit.SECONDS);
}
public void stop() {
if(future != null) future.cancel();
}
[/编辑]
此处有更多详情 - &gt; http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledFuture.html