0

我有一个问题ScheduledThreadPoolExecutor

我需要一个超时,它将在之后重定向到第一页'n'-seconds。如果用户输入一个字符,计时器应该重新开始计数,并且可能不会重定向到第一页。(所以计数器应该中止他的预定任务)

问题是,计时器启动,但如果键入一个键,它不会取消计划的任务。-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();
        }
    });
}
4

1 回答 1

1

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

shutdownNow()不保证取消执行。

至于解决方案,我建议您使用ScheduledFutureor Futureobjects 而不是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();
}

[/编辑]

更多细节在这里-> http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledFuture.html

于 2013-09-02T08:54:07.053 回答