简体   繁体   English

非活动用户的Java超时

[英]Java Timeout for an inactive user

I have a problem with the ScheduledThreadPoolExecutor . 我对ScheduledThreadPoolExecutor有问题。

I need a timeout which will redirect to the first page after 'n'-seconds . 我需要一个超时时间,该超时时间将在'n'-seconds后重定向到首页。 If the user enters a character, the timer should start counting again and may not redirect to the first page. 如果用户输入一个字符,计时器应重新开始计数,并且可能无法重定向到第一页。 (So the counter should abort his scheduled Task) (因此计数器应中止其计划的任务)

The Problem is, that the Timer starts, but it doesn't cancel the scheduled Task if a key was typed. 问题是计时器启动了,但是如果键入了键,它不会取消计划的任务。 The stop() - Method will be called. stop() -方法将被调用。 But scheduledThreadPool.shutdownNow(); 但是scheduledThreadPool.shutdownNow(); seems not to work. 似乎不起作用。

My TimerClass looks like this: 我的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();
    }
}

The method in a superclass which calls the timerClass is this one: 超类中调用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();
    }
}

The KeyListener and the MouseClickListener will be set on the scene at the beginning by this method: 可以通过以下方法在开始时在场景中设置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();
        }
    });
}

Take a look at this -> http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html 看看这个-> http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html

The shutdownNow() makes no guarantees to cancel execution. shutdownNow()不保证取消执行。

As for a solution, I recommend you use ScheduledFuture or Future objects rather than Runnable . 对于解决方案,建议您使用ScheduledFutureFuture对象,而不要使用Runnable

[EDIT] A scheduled future, on which you can call a .cancel() function instead of .shutdownNow() is returned by the .schedule() call, which you call, but don't seem to use (or indeed save) the handle to the Future anywhere. [编辑]一个预定的将来,可以在其上调用.cancel()函数,而不是.shutdownNow()被返回的.schedule()调用,调用,但似乎并没有使用(或实际上保存)任何地方的Future And yes, you do still need a Runnable but only insofar as it will give you the Future handle. 是的,您仍然需要一个Runnable但前提是它会给您Future手柄。

Try something like this: 尝试这样的事情:

private ScheduledFuture<?> future;
public void start() {
    future = scheduledThreadPool.schedule(logicalWorker, delay, TimeUnit.SECONDS);
}
public void stop() {
    if(future != null) future.cancel();
}

[/EDIT] [/编辑]

More details here -> http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledFuture.html 此处有更多详细信息-> http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledFuture.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM