The correct way to deal with a thread that needs to be stopped is to design the thread's code so that it responds appropriately to being interrupted:
Long computations need to occasionally check the current thread's "interrupted" flag.
InterruptedException
should be handled appropriately.
The thread application code's response to the interrupt should be to gracefully stop what it is doing1 and (typically) allow the thread to terminate.
(You could also use a custom flag implemented using a volatile
shared variable instead of the interrupted flag. However, that doesn't deal with interrupting wait
, sleep
and similar operations, and is therefore a poor substitute for interrupts.)
The unsafe way is to call the deprecated Thread.stop()
method. (The javadocs explain why it is unsafe, and we don't need to repeat that here.)
The (related) Thread.stop(Throwable)
method was removed in Java 11; see:
Unfortunately, there is nothing in between these two approaches for interrupting a thread.
If you cannot get your long running thread to cooperate, the safe alternative would be to run it in a separate process; e.g. using System.ProcessBuilder
etcetera to run the java
command. The (external) process could then be killed if it took too long. The downsides include:
An external process cannot access the current JVM's variables, etcetera. So you need to use a different mechanism to pass information between the parent and child processes.
Starting a new JVM is a lot more expensive than starting a new thread.
1 - For example, if the thread owns resources such as open files or sockets, it should release them. If it is performing an action for some other thread that will be waiting for the result, it should signal (in the appropriate way) that there will be no result. And so on.