【问题标题】:A Timer() thread still running after cancelling itTimer() 线程取消后仍在运行
【发布时间】:2014-05-06 01:44:55
【问题描述】:

我不知道为什么即使我取消了线程仍然活着?在Timer 线程下面的代码中实现runnable 并且在代码中我希望它使用Thread.sleep(7000); 保持运行7 秒,然后我调用mTimer.cancel(); 来杀死线程。在 7 秒内,应调用 run() 方法来执行将持续 10 秒的任务。当我执行那个程序时,第一行的时间是12:18:37,正如我所料,因为这个线程在我取消它之前只会存活7秒,但是第二行显示的时间是05 12:18:44,现在这是7秒的差异,这是合理的。但出乎意料的是,3 秒后控制台上出现了另一行,时间为05 12:18:47。如果您注意到第一行和第三行之间的差异,您会发现 10 秒。我的问题是,为什么整个线程在 7 秒后没有死。

Java代码:

public class TimerTaskExample extends TimerTask {
private static Timer mTimer;

@Override
public void run() {
    // TODO Auto-generated method stub
    System.out.println("going to sleep at: " + new Date());
    dosomeWorks();
    System.out.println("returned back at: " + new Date());
}

private void dosomeWorks() {
    // TODO Auto-generated method stub
    try {
        Thread.sleep(10000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

public static void main(String args[]) {
    TimerTask timerTask = new TimerTaskExample();
    mTimer = new Timer(true);
    mTimer.scheduleAtFixedRate(timerTask, new Date(), 2*1000);
    //System.out.println("timer will start now at: " + new Date());
    try {
        Thread.sleep(7000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    mTimer.cancel();
     System.out.println("timer is cancelled now at: " + new Date());
     try {
        Thread.sleep(3000);
            } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

}

输出:

going to sleep at: Mon May 05 12:18:37 CEST 2014
timer is cancelled now at: Mon May 05 12:18:44 CEST 2014
returned back at: Mon May 05 12:18:47 CEST 2014

【问题讨论】:

  • 合乎逻辑的结论是你不能立即取消一个休眠线程。

标签: java android multithreading timer


【解决方案1】:

取消 TimerTask 不会中断它的执行 - 它只是阻止它再次执行。

如果您希望线程停止执行,您需要在某处存储对 java.lang.Thread 的引用并中断它。

假设您在线程中进行实际工作,您还需要轮询 Thread.interrupted() 以检查它是否应该继续。

private Thread taskThread;

@Override
public void run() {
    taskThread = Thread.currentThread();
    System.out.println("going to sleep at: " + new Date());
    doSomeWorks();
    System.out.println("returned back at: " + new Date());
}

private void dosomeWorks() {
    for (int i = 0; !Thread.interrupted() && i < 10; ++i) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

...
mTimer.cancel();
timerTask.taskThread.interrupt();
...

请务必阅读 Thread.interrupt() 的 javadoc,以确保您知道它确实如此。

【讨论】:

    猜你喜欢
    • 2018-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多