How to Kill a Thread? Without Using Stop();

How to properly stop the Thread in Java?

In the IndexProcessor class you need a way of setting a flag which informs the thread that it will need to terminate, similar to the variable run that you have used just in the class scope.

When you wish to stop the thread, you set this flag and call join() on the thread and wait for it to finish.

Make sure that the flag is thread safe by using a volatile variable or by using getter and setter methods which are synchronised with the variable being used as the flag.

public class IndexProcessor implements Runnable {

private static final Logger LOGGER = LoggerFactory.getLogger(IndexProcessor.class);
private volatile boolean running = true;

public void terminate() {
running = false;
}

@Override
public void run() {
while (running) {
try {
LOGGER.debug("Sleeping...");
Thread.sleep((long) 15000);

LOGGER.debug("Processing");
} catch (InterruptedException e) {
LOGGER.error("Exception", e);
running = false;
}
}

}
}

Then in SearchEngineContextListener:

public class SearchEngineContextListener implements ServletContextListener {

private static final Logger LOGGER = LoggerFactory.getLogger(SearchEngineContextListener.class);

private Thread thread = null;
private IndexProcessor runnable = null;

@Override
public void contextInitialized(ServletContextEvent event) {
runnable = new IndexProcessor();
thread = new Thread(runnable);
LOGGER.debug("Starting thread: " + thread);
thread.start();
LOGGER.debug("Background process successfully started.");
}

@Override
public void contextDestroyed(ServletContextEvent event) {
LOGGER.debug("Stopping thread: " + thread);
if (thread != null) {
runnable.terminate();
thread.join();
LOGGER.debug("Thread successfully stopped.");
}
}
}

How can I immediately terminate a Thread? (Not interrupt)

I believe that there's no way in Java to just kill off a thread like you're describing. As you note in a comment, interrupt won't do what you want. If the thread is executing, it just sets a flag and it's up to the thread to notice it. if the thread is waiting or sleeping, it will throw an InterruptedException.

The only way I can imagine doing what you're describing is to kill the process in which the thread is running. (E.g., call System.exit(int).)

Is there any way to kill a Thread?

It is generally a bad pattern to kill a thread abruptly, in Python, and in any language. Think of the following cases:

  • the thread is holding a critical resource that must be closed properly
  • the thread has created several other threads that must be killed as well.

The nice way of handling this, if you can afford it (if you are managing your own threads), is to have an exit_request flag that each thread checks on a regular interval to see if it is time for it to exit.

For example:

import threading

class StoppableThread(threading.Thread):
"""Thread class with a stop() method. The thread itself has to check
regularly for the stopped() condition."""

def __init__(self, *args, **kwargs):
super(StoppableThread, self).__init__(*args, **kwargs)
self._stop_event = threading.Event()

def stop(self):
self._stop_event.set()

def stopped(self):
return self._stop_event.is_set()

In this code, you should call stop() on the thread when you want it to exit, and wait for the thread to exit properly using join(). The thread should check the stop flag at regular intervals.

There are cases, however, when you really need to kill a thread. An example is when you are wrapping an external library that is busy for long calls, and you want to interrupt it.

The following code allows (with some restrictions) to raise an Exception in a Python thread:

def _async_raise(tid, exctype):
'''Raises an exception in the threads with id tid'''
if not inspect.isclass(exctype):
raise TypeError("Only types can be raised (not instances)")
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(tid),
ctypes.py_object(exctype))
if res == 0:
raise ValueError("invalid thread id")
elif res != 1:
# "if it returns a number greater than one, you're in trouble,
# and you should call it again with exc=NULL to revert the effect"
ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(tid), None)
raise SystemError("PyThreadState_SetAsyncExc failed")

class ThreadWithExc(threading.Thread):
'''A thread class that supports raising an exception in the thread from
another thread.
'''
def _get_my_tid(self):
"""determines this (self's) thread id

CAREFUL: this function is executed in the context of the caller
thread, to get the identity of the thread represented by this
instance.
"""
if not self.isAlive():
raise threading.ThreadError("the thread is not active")

# do we have it cached?
if hasattr(self, "_thread_id"):
return self._thread_id

# no, look for it in the _active dict
for tid, tobj in threading._active.items():
if tobj is self:
self._thread_id = tid
return tid

# TODO: in python 2.6, there's a simpler way to do: self.ident

raise AssertionError("could not determine the thread's id")

def raiseExc(self, exctype):
"""Raises the given exception type in the context of this thread.

If the thread is busy in a system call (time.sleep(),
socket.accept(), ...), the exception is simply ignored.

If you are sure that your exception should terminate the thread,
one way to ensure that it works is:

t = ThreadWithExc( ... )
...
t.raiseExc( SomeException )
while t.isAlive():
time.sleep( 0.1 )
t.raiseExc( SomeException )

If the exception is to be caught by the thread, you need a way to
check that your thread has caught it.

CAREFUL: this function is executed in the context of the
caller thread, to raise an exception in the context of the
thread represented by this instance.
"""
_async_raise( self._get_my_tid(), exctype )

(Based on Killable Threads by Tomer Filiba. The quote about the return value of PyThreadState_SetAsyncExc appears to be from an old version of Python.)

As noted in the documentation, this is not a magic bullet because if the thread is busy outside the Python interpreter, it will not catch the interruption.

A good usage pattern of this code is to have the thread catch a specific exception and perform the cleanup. That way, you can interrupt a task and still have proper cleanup.

How do you kill a Thread in Java?

See this thread by Sun on why they deprecated Thread.stop(). It goes into detail about why this was a bad method and what should be done to safely stop threads in general.

The way they recommend is to use a shared variable as a flag which asks the background thread to stop. This variable can then be set by a different object requesting the thread terminate.

How to interrupt or kill a java thread while it's running

The way you stop a thread is by asking it - nicely - to stop. It's up to the code the thread is running to listen for and act on that request.

Specifically, the way you do it is to interrupt the thread. Your code checks for the interruption - Thread.sleep and Object.wait will throw InterruptedException if the thread is interrupted before or during their execution; but you catch the interruption, and ignore it, so you won't act on it.

Instead of this:

while (condition) {
try {
Thread.sleep(...);

wait();
} catch (InterruptedException e) {
}
}

Put the interruption outside the loop:

try {
while (condition) {
Thread.sleep(...);
wait();
}
} catch (InterruptedException e) {
}

then the loop terminates if it is interrupted.

Alternate to Thread.stop() in Java 8?

If you really need to stop a Thread the hard way you may consider that the method Thread.stop() (without providing an arbitrary Throwable) still works with Java 8. It will generate a ThreadDeath on the stopped thread which can be handled like any other Error, despite its unusual name. The only difference is that no stack trace will be printed if ThreadDeath is not caught.


But beware that this method is deprecated for most of the same reasons than the other stop method. It might become unspported in one of the next releases of Java. So it’s still time to think about a plan B…



Related Topics



Leave a reply



Submit