Java: How to Stop Thread

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.

Stop thread from other class

There is no need to call Thread.stop().

The reason why your code doesn't currently stop when you interrupt the thread is that the handling of the interruption occurs inside the loop:

for (int i = countdown; i >= 0; i--) {
// ...
try {
// Sleep
} catch (InterruptedException e) {
}
}

When the thread is interrupted during (or before) the sleep, the interruption is "swallowed": you handle it, so the loop just continues on to the next iteration, if any.

There's a Robin Williams skit about British police, who, owing to their lack of guns, have to say "Stop! Or.... I'll say stop again!". If you kept calling interrupt, eventually your thread would finish, because eventually the loop would execute the appropriate number of times. But this would be really messy, and is quite unnecessary.

Reverse the order of the loop and the try/catch:

try {
for (int i = countdown; i >= 0; i--) {
// ...

// Sleep
}
} catch (InterruptedException e) {
}

Now, when the interruption occurs, execution moves to after the loop, so no more loop iterations occur.

(Of course, you could leave your code as it is, and just return from the catch; but multiple return points can make the code harder to reason about)


You should also consider re-interrupting the current thread when you catch the InterruptedException:

// ...
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}

This sets the interrupted flag on the current thread (confusingly, this is orthogonal to InterruptedException), allowing any code calling the Runnable to know that the thread was interrupted.

It's not strictly necessary to do this: if you know that the code is at the top of a thread's call stack (like here: there is no "caller" to be made aware of interruption). But re-interrupting the thread is nearly always the right thing to do (*), and doesn't actually hurt at all in this case.

(*) An example of when you wouldn't is if you are rethrowing the InterruptedException, or if you are writing threading framework code, and you know for sure it is the right thing not to.

Java break or exit from a thread

you can simply call return without a value to exit a void method earlier.

public void run() {
boolean success = performTask();

if( success == false ){
return; //ends the thread
}
// further processing if success == true
}

Java - Stop a thread automatically when program ends

The thread you are creating is independent and does not depend on the Main Thread termination. You can use Daemon thread for the same. Daemon threads will be terminated by the JVM when there are none of the other non- daemon threads running, it includes a main thread of execution as well.

public static void main(String[] args) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
System.out.println("Daemon thread");
}
}
});
t.setDaemon(true);
t.start();

System.out.println("End of main");
}

Stop thread from inside and notify from outside

I can think of several schools of thought:

The first one is to have 2 threads, as in your example. They can share several types of objects through which thread2 can notify thread1.

Using java.util.concurrent.Condition:

// thread1
public void run() {
// to wait
lock.lock();
try {
condition.await();
} finally {
lock.unlock();
}
}

//thread2
public void run() {
// to notify
lock.lock();
try {
condition.signal();
} finally {
lock.unlock();
}
}

You can also use CyclicBarrier, and maybe other types.

The second school of thought is to have a single work thread, which executes the other using ExecutorService:

// thread2
public void run() {
executorService.execute(new RunnableThread1());
}

This concept looks at the work done by thread1 as a detached task which can be executed multiple times. So this may not be compatible with your program.

And the last option is to use Thread.interrupt:

//thread1
public void run() {
while (true) {
try {
Thread.sleep(sleepTime);
} catch(InterruptedException e) {
// signaled.
}
}
}

//thread 2
public void run() {
thread1.interrupt();
}

This may be a bit problematic since the interrupt call is better used to stop threads and not to signal them.

Thread.stop() - deprecated

You asked:

My question is if theres no way to stop a thread in Java then how to stop a thread?

The Answer: In Java there's no clean, quick or reliable way to stop a thread.

Thread termination is not so straight forward. A running thread, often called by many writers as a light-weight process, has its own stack and is the master of its own destiny (well daemons are). It may own files and sockets. It may hold locks. Abrupt Termination is not always easy: Unpredictable consequences may arise if the thread is in the middle of writing to a file and is killed before it can finish writing. Or what about the monitor locks held by the thread when it is shot in the head?

Instead, Threads rely on a cooperative mechanism called Interruption. This means that Threads could only signal other threads to stop, not force them to stop.

To stop threads in Java, we rely on a co-operative mechanism called Interruption. The concept is very simple. To stop a thread, all we can do is deliver it a signal, aka interrupt it, requesting that the thread stops itself at the next available opportunity. That’s all. There is no telling what the receiver thread might do with the signal: it may not even bother to check the signal; or even worse ignore it.

Source: https://codeahoy.com/java/How-To-Stop-Threads-Safely/

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;
}


Related Topics



Leave a reply



Submit