非活动用户的Java超时

时间:2013-09-02 08:20:31

标签: java concurrency javafx-2

我对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();
        }
    });
}

1 个答案:

答案 0 :(得分:1)

看看这个 - &gt; http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html

shutdownNow()不保证取消执行。

对于解决方案,我建议您使用ScheduledFutureFuture个对象,而不是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