How to Properly Stop the Thread in Java

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 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 stop a thread from inside?

A thread terminates when its run method completes. The return statement terminates a method. Since method run returns no value, simply writing return in the if block will terminate the method and subsequently, the thread.

if(/* We don't meet certain requirements for continuing */) {
return;
}

How to stop currentThread in Java?

You can just kill the thread from the inside, meaning throwing an Exception or Error that you never catch, and it just gets propagated upward the calling stack:

public void failure() {
// as you're using a test, an assertion error may be a suitable option
throw new AssertionError("Test failure");
}

You also don't have to worry that your main method is affected by this, because exceptions from Threads other than the main-Thread will not be propagate all the way upwards.

Do I need to stop a Thread?

If you do not have a permanent loop or something similar inside the Runnable, then no you don't need to.

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.

Reliably stopping an unresponsive thread

It may not be possible, at least not reliably in every scenario.

IF I understand the mechanism correctly (and there is some uncertainty there), if the code executes in such a way that there are no safepoints during the execution (for example in counted loops), it is not possible for the JVM to signal to the thread that it should stop (the thread never polls for an interrupt).

In such a scenario, you need to kill the JVM process, rather than the thread.

Some extra reading:

How to get Java stacks when JVM can't reach a safepoint

Counted loops



Related Topics



Leave a reply



Submit