从另一个线程调用timer.cancel()后,TimerTask不会立即停止?

时间:2017-08-03 12:59:11

标签: java multithreading timertask

我有一个小程序可以执行以下操作: 主线程和线程t1周期性地请求一些东西,一个按钮将停止两者。

public class HttpsConn {
    private static boolean stop = false;
    private static Timer t = null;

    public static void main(String[] arg)  {
        t = new Timer();
        A a = new A();
        t.schedule(a, 0, 1000);
        B b = new B();
        Thread t1 = new Thread(b);
        t1.start();
    }
    static class A extends TimerTask {
        @Override
        public void run() {
            if (stop)
                t.cancel();     //this.cancel();
            System.out.println("something to do");
        }
    }
    static class B extends A implements Runnable {
        @Override
        public void run() {
            System.out.println("simulate an operation from Swing Applet (click RESET button) to interrupt the thread.");
             stop = true;
        }
    }
}

我除了结果:

something to do
simulate an operation from Swing Applet (click RESET button) to interrupt the thread.

我得到了什么:

something to do
simulate an operation from Swing Applet (click RESET button) to interrupt the thread.
something to do

我找到了一个类似的问题here,答案说在run()中调用取消,但这似乎不起作用。 那么如何避免意外运行呢? 评论一行中t.cancel()this.cancel()之间有什么区别?他们导致相同的结果。 谢谢!

1 个答案:

答案 0 :(得分:0)

您的1计划以something to do的初始延迟以及随后的0秒延迟投放。

第一个stop是第一次Timer延迟后执行。 stop标志尚未设置,因此只打印并退出。

一秒后,B再次调用它。它检查something to do标志,取消定时器(因为 if (!stop) { System.out.println("something to do"); } else { t.cancel(); //this.cancel(); } 已执行并设置它)并打印第二个cancel。它不应该再次运行,因为计时器任务现在已被取消。

为了避免这种看似奇怪的行为,您可以使用以下内容:

Timer

请注意,Runnable仅取消fd,但不会中止seth 0 fd的执行。