Question

I do not know why the thread is still alive even after i cancel it? in the code below the Timer thread implements runnable and in the code i want it to stay running for 7 seconds using Thread.sleep(7000);and after that i called mTimer.cancel(); to kill the thread. during the 7 seconds the run() method should be called to execute a task that will last for 10 seconds. When i executed that program, the time of the first line was 12:18:37 and as i expected, since this thread will live only for 7 seconds before i cancel it, however the time of second line to be displayed was 05 12:18:44, now this is 7 seconds difference and it is rational. But unexpectedly, after 3 seconds another line appeared on the console and it was timed to 05 12:18:47. If you noticed the difference between the first and the third line you will find it 10 seconds.My question is, why the entire thread did not die after 7 seconds.

JavaCode:

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();
    }
}

}

Output:

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
Was it helpful?

Solution

Cancelling a TimerTask does not interrupt it's execution - it just prevents it from being executed again.

If you want the thread to stop executing you need to stash a reference to the java.lang.Thread somewhere and interrupt it.

Assuming that you're doing real work in the thread you also need to poll Thread.interrupted() to check if it should continue.

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();
...

Be sure to read the javadoc for Thread.interrupt() to be sure you know it actually does.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top