【问题标题】:How to cancel an already scheduled TimerTask?如何取消已经安排好的 TimerTask?
【发布时间】:2014-11-05 13:01:40
【问题描述】:

我有一个小问题,我似乎做不好。我在java中有以下类:

package pooledtcpconnector.utilities;

import java.io.IOException;
import java.io.InputStream;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;

public final class Notifier implements Runnable {

    private final ILogger logger;

    private Timer mTimer;
    private final int Treshold;
    private final InputStream ResponseStream;
    private final TimerTask DoWaitTask;

    public Notifier(final InputStream _ResponseStream, final Integer _Treshold, final ILogger logger) {
        this.logger = logger;

        mTimer = new Timer();

        this.ResponseStream = _ResponseStream;
        this.Treshold = _Treshold;

        DoWaitTask = new TimerTask() {
            @Override
            public void run() {
                try {
                    int mSize = ResponseStream.available();
                    if (mSize >= Treshold) {
                        mTimer.cancel();
                    }
                } catch (final IOException ex) {
                    final String ExceptionMessage = ex.getMessage();
                    logger.LogMessage(
                            this.getClass().getCanonicalName(),
                            "Notifier.DoWaitTask:run.ResponseStream.available",
                            ex.getClass().getCanonicalName(),
                            new String[]{
                                ExceptionMessage,
                                "Parameters:",
                                String.format("-"),
                            });

                    Logger.getLogger(Notifier.class.getCanonicalName()).log(Level.FINE, ex.getMessage(), ex.getCause());
                }
            }
        };
    }

    @Override
    public void run() {
        synchronized (this) {
            mTimer.scheduleAtFixedRate(DoWaitTask, 250, 200);
            // Notification mechanism
            notify();
        }
    }

}

此类将确保我们的应用程序不会开始处理 SocketInputStream,除非可用方法至少返回 Treshold。然而问题是,一旦我用 Timer 安排 DoWaitTask ,它就会永远运行。通过取消计时器,任务仍然运行并且整个应用程序挂起,但更重要的是,一旦它已经被处理和关闭,它就会尝试在流上调用可用。当然,这会导致一个不错的 IOException: stream closed。

如何停止计划任务和计时器? timer.cancel 显然是不够的。

问候, 乔伊

【问题讨论】:

    标签: java timer timertask


    【解决方案1】:

    私人计时器reportTimer = null;

        if (reportTimer != null) {
            reportTimer.cancel();
            reportTimer = null;
        }
    
        reportTimer = new Timer();
        reportTimer.schedule(new TimerTask() {}
    

    【讨论】:

      【解决方案2】:

      在计时器任务的 run() 方法中使用 TimerTask.cancel()。根据此方法的 Javadoc:

      请注意,从 a 的 run 方法中调用此方法 重复定时器任务绝对保证定时器任务将 不再运行。

      【讨论】: