CodeGym /Courses /Java Core /Stopping threads: the official version

Stopping threads: the official version

Java Core
Level 6 , Lesson 9
Available

"Hello, Amigo! You have to admit that Ellie's Cancel idea was brilliant."

"Yep."

"Actually, something similar exists in the Thread class. Only the variable isn't called isCancel. It's called isInterrupt. And the method used to stop the thread isn't cancel(). It's interrupt()."

"Really?"

"Yes. Check it out:"

Code Description
class Clock implements Runnable
{
public void run()
{
Thread current = Thread.currentThread();

while (!current.isInterrupted())
{
Thread.sleep(1000);
System.out.println("Tick");
}
}
}
Because several threads can call the run method on the same Clock object, we get the Thread object for the current thread.

The Clock class writes the word "Tick" to the console once a second as long as the current thread's isInterrupt variable is false.

When isInterrupt becomes true, the run method terminates.

public static void main(String[] args)
{
Clock clock = new Clock(); Thread clockThread = new Thread(clock); clockThread.start();

Thread.sleep(10000);
clockThread.interrupt();
}
The main thread starts a child thread (clock) that should run forever.

Wait 10 seconds and cancel the task by calling the interrupt method.

The main thread completes its work.

The clock thread ends its work.

Moreover, the sleep method, which people are so fond of using in endless loops in the run method, automatically checks the isInterrupt variable. If a thread calls the sleep method, the method first checks whether isInterrupt is true for that thread. If it is true, the method won't sleep. Instead, it throws an InterruptedException exception.

"Why throw an exception? Wouldn't it be better to simply put isInterrupted() instead of isCancel() in a loop?"

"First, the run method doesn't always have a loop. The method might simply consist of a few dozen calls to other methods. Then you would have to add an isInterrupted check before each method call."

"Second, some method that involves lots of different actions might take a very long time to execute."

"Third, throwing an exception doesn't replace the isInterrupted check. It's just a convenient addition. The thrown exception lets you to quickly unwind the call stack back to the run method itself."

"Fourth, the sleep method is used a lot. As it turns out, this helpful method is enhanced by an implicit check that is no less helpful. It's as if nobody specifically added the check, but there it is. This is super valuable when you're using someone else's code and you can't add the check yourself."

"Fifth, the additional check doesn't degrade performance. Calling the sleep method means that the thread shouldn't be doing anything (except sleeping), so the extra work doesn't bother anyone."

"Those are serious arguments."

"And, finally, there's this: Your run method can call someone else's code—code that you don't have access to (source code and/or rights to change the code). It might not have isInterrupted checks, and it might use "try ... catch (Exception e)" to catch all exceptions."

Nobody can guarantee that a thread will be stopped. Only a thread can stop itself.

Comments (11)
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION
Gellert Varga Level 23, Szekesfehervar, Hungary
5 April 2021
I did several tests with the example codes above. My experience with them is this: sometimes the child thread was interrupted, and sometimes it wasn’t (= i got the executing of an endless loop.) More about this phenomenon in this help section post: https://codegym.cc/help/15086
Jonaskinny Level 25, Redondo Beach, United States
10 March 2022
Only guarantees I know of to stop a thread cold ... System.exit() & physically pulling the plug. The reason for the discrepancies could be arithmetic combined with processor speed, any other process load. 1000 milliseconds does not always equate to 4 * (1/4 of 1000) milliseconds if you have to do anything else while waiting for those increments. So if 4 x 250 + a little other processing time > 1000 you will see maybe 1 or 2 misses. * reposted this from my response to your expanded question
Vahan Level 41, Tbilisi, Georgia
27 September 2019
But given code doesn't terminate program, only interrupts an then it continues....
Artur Verdyan Level 24, Hoboken, United States
30 April 2020
I see the same. Interesting... Well, I guess if you get an exception, at least you may act on it, so maybe placing "break" in the run method that is what we might consider.

 try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    break;
                }
Vahan Level 41, Tbilisi, Georgia
1 May 2020
Right. Also clockThread can be set daemon for that purpose. I know it for now.
Jen P Level 26
3 August 2019
For me, it seems that the articiles does not answer this question well "Wouldn't it be better to simply put isInterrupted() instead of isCancel() in a loop?" I mean I am still confused why we should use the words isInterrupted() instead of isCancel();
Daniel Walbolt Level 22, Waterville, United States
9 July 2020
Only because the Thread object already contains the method: "isInterrupted()" and it returns a boolean stating if it is or isn't.
Henk Level 19, Pretoria, South-Africa
28 May 2019
using different names makes no sense to me, the new Java programmer... All I read, is that they WANTED to use the words isInterrupted() instead of isCancel(); Words are words are words, same thing. It stops the thread you're trying to stop. We do it all the time in similar programming, e.g. while loop and break statement for condition not true. But like I say, this will probably be more "REAL" to me one day after 4 years of Java coding...so no harm.
Darko Jakimovski Level 18, Kriva Palanka, Macedonia, The Former Yugoslav Republic of
22 May 2019
Why would we need a Thread object in the Clock's run method? Can anyone explain please?
Oleg Tokarenko Level 19, L'viv, Ukraine
25 May 2019
"Because several threads can call the run method on the same Clock object, we get the Thread object for the current thread." i.e. that the Clock object can be used by other threads, therefore, the run() method needs to know the specific thread that uses Clock object.
Krisztian Level 24, Budapest, Hungary
25 June 2019
I have another explanation: because the isInterrupted check. you could call the isInterrupted() method only on a Thread object. so first you should specify the current used thread for the program.