"Hi, Amigo!

"Everything new is just something old that we've forgotten. Today I'll talk about stopping threads. I hope you've already forgotten how the interrupt() method works."

"Yes, Ellie, I've completely forgotten it."

"Great. Then I'll remind you."

"In Java, if someone wants to stop a running thread, he can signal this to the thread. To do this, you need to set the Thread object's hidden isInterrupted variable to true."

"Each Thread has an interrupt() method, which is used to set this flag. When the interrupt() method is called, the isInterrupted variable inside the Thread object is set to true."

"And when the Thread.sleep() or join() method is called on a thread, the method checks whether the isInterrupted flag is set for the current thread. If this flag is set (the variable isInterrupted equals true), then the methods throw an InterruptedException."

"Here, I'll remind you of an old example:"

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

while (!current.isInterrupted())
{
Thread.sleep(1000);
System.out.println("Tik");
}
}
}
The Clock's run method gets the Thread object for the current thread.

The Clock class writes the word "Tick" to the console once per 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 finishes its work.

The clock thread finishes its work.

"Here we use the sleep method as part of an infinite loop in the run method. In the loop, the isInterrupt variable is checked automatically. If a thread calls the sleep method, the method first checks whether isInterrupt is true for that thread (the one that called the sleep method). If it is true, then the method won't sleep. Instead, it throws an InterruptedException."

"But in this example, we constantly check the isInterrupted variable in the loop's condition."

"I remember there were some reasons why we couldn't use this approach. Could you remind me?"

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

"Second, some method involving 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. It turns out that 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."

"That's exactly what you said previously."

"And what about your statement, «Nobody can guarantee that a thread will be stopped. Only a thread can stop itself.» Can you explain that?"

"Sure."

"Previously, in early versions of Java, threads had a stop() method. And when you called it, the JVM actually stopped the thread. But if a thread was doing something outside the JVM (for example, writing to a file or calling OS functions) when it was interrupted this way, the interruption caused a lot of problems, such as unclosed files, unreleased system resources, etc."

"A general meeting of Java's creators decided to remove the method for forcibly stopping threads. Now all we can do is set a certain flag (isInterrupted) and hope that the thread code was written correctly, so that this flag will be processed. This flag is like a sign that says, 'Thread, stop, please. It's very important!'. But whether it stops or not is its own business."

"But what about the InterruptedException?"

"What if the code running on this thread has a bunch of try-catch blocks? Even if an InterruptedException occurs somewhere, there's definitely no guarantee that some try-catch won't catch it and forget about it. So there are no guarantees the thread will stop."

"Another thing is that threads are already considered quite low-level programming. But I'll tell you about that next time."

"You're not Ellie—you're Scheherazade!"

"So, Amigo! Is everything in the current lesson clear?"

"Yep."

"Okay, good."