Friday, September 15, 2023

How to Stop a Thread in Java? Code Example

The thread is one of the important Classes in Java and multithreading is the most widely used feature, but there is no clear way to stop Thread in Java. Earlier there was a stop method that exists in Thread Class but Java deprecated that method citing some safety reasons. By default, a Thread stops when the execution of run() method finishes either normally or due to any Exception. In this article, we will How to Stop Thread in Java by using a boolean State variable or flag.

Using a flag to stop Thread is a very popular way of stopping the thread and it's also safe because it doesn't do anything special rather than helping run() method to finish itself.



How to Stop Thread in Java? Example

As I said earlier Thread in Java will stop once the run() method is finished. Another important point is that you can not restart a Thread which run() method has finished already, you will get an IllegalStateExceptio, here is a Sample Code for Stopping Thread in Java.



Sample Code to Stop Thread in Java


    private class Runner extends Thread{
    boolean bExit = false;
  
    public void exit(boolean bExit){
        this.bExit = bExit;
    }
  
    @Override
    public void run(){
        while(!bExit){
            System.out.println("Thread is running");
                try {
                    Thread.sleep(500);
                } catch (InterruptedException ex) {
                    Logger.getLogger(ThreadTester.class.getName()).log(Level.SEVERE, null, ex);
                }
        }
    }
}
    
    
And, if you are wondering what this code do, here is full explanation:

This code defines a Java class called Runner that extends the Thread class, making it a thread itself. This Runner class is designed to run a thread that repeatedly prints "Thread is running" to the console until a specific condition (bExit) becomes true.

Here's an explanation of the key components and methods in this code:

boolean bExit: This is an instance variable (or field) of the Runner class, which is a boolean flag used to control the thread's execution. It is initially set to false.

public void exit(boolean bExit): This is a method defined within the Runner class. It allows external code to set the bExit flag, controlling when the thread should exit. When you call this method with true as the argument, it sets bExit to true, indicating that the thread should stop running.

@Override annotation: This annotation indicates that the following method (run()) is an overridden method from the Thread class. The run() method is executed when you start the thread using the start() method.

public void run(): This is the method that contains the main logic of the thread. It runs in a loop until the bExit flag becomes true. 

Inside the loop:

It prints "Thread is running" to the console.
It then sleeps the thread for 500 milliseconds (half a second) using Thread.sleep(500). This sleep simulates some work being done by the thread.


The thread will continue running this loop, periodically printing "Thread is running" and sleeping, until something outside the Runner class calls the exit(true) method, setting bExit to true. When bExit becomes true, the loop will exit, and the thread will stop running.

In practice, you would create an instance of the Runner class, start it using the start() method, and then, when you want the thread to stop, call the exit(true) method to signal the thread to exit gracefully. This is a simple way to control the lifecycle of a thread and have it perform specific tasks until you decide to stop it.

And, if you are wondering about thread lifecycle in Java, here is a nice diagram which explains how threads are created, waited, put on hold and stopped in Java:

thread lifecycle in Java



Should we make bExit Volatile?

How to Stop Thread in Java Tutorial ExampleSince every thread has its own local memory in Java it's best practice to make bExit volatile because we may alter the value of bExit from any thread and make it volatile guarantees that Runner will also see any update done before making bExit.

If you don't make it volatile, it may be possible for a thread to cache its value and keep running even if another thread has set the bExit=true, so thread will not be stopped in time.  

Hence its safe to make the bExit boolean variable volatile in Java. 


That’s all on how to stop the thread in Java. This one is a simple and easy way to stop a thread in Java but you should consider using Executor or ForkJoin Pool instead of creating and stopping thread manually. It's much better for Java developer to leverage thread pool to achieve concurrency and parallelism then coding your own. You can also use the parallelStream() method to run task in parallel.

Als, let me know if you find any other way of stopping threads in Java without using the deprecated stop() method.



Related Java Multi-threading Post:

P. S. - And, if you are serious about mastering Java multi-threading and concurrency then I also suggest you take a look at these Java Concurrency and Multithreading Courses. It's an advanced resource to become an expert in Multithreading, concurrency, and Parallel programming in Java with a strong emphasis on high performance

And lastly, one question for you? Why do you think Thread.stop() is deprecated? and is time to not use Thread directly and instead use Thread with Executor and ForkJoinPool?

18 comments:

  1. The reason you can't just stop a thread is actually fairly simple. What if it's allocated resources, and is in the middle of work? If you do a hard stop, that may just leave a lot of stuff hanging. So, instead you basically send it a message and it stops at it's own convenience (if implemented properly). Basically they pushed back that part of the behavior to the programmers.

    ReplyDelete
  2. Thanks for your Comments Paul. but isn't it Java's main idea is to do common stuff by JVM and not by programmer e.g. Memory Management is done by Garbage Collection , they can easily provide a shutdown or kill thread like method, isn't it ?

    ReplyDelete
  3. Another way to stop a running thread is to set the thread object as null.

    Pankaj

    ReplyDelete
  4. Hi Pankaj, I doubt that will work, simply setting thread object null will not stop thread in my opinion, have you tried it ?

    ReplyDelete
  5. How to Kill a thread or how to stop a thread is just waste of time you can do better job with Executor framework, let the framework start and kill thread rather than you.

    ReplyDelete
  6. How about using interrupt and check the interrupt flag on the thread and stop if it has been interrupted? If the thread is in a non-blocking state, it will ignore it. However, if it reaches a blocking call such as wait/sleep it will throw an InterruptedException.

    ReplyDelete
  7. You cannot simply kill a thread because if it owns any locks (ie if it's in the middle of a synchronized block when you kill it) those locks won't be released leaving your program in a state where it will certainly deadlock. Its an OS thing, but that's why. While the example provided here works and adding volatile, blah, blah, blah. I don't think it really gives any insight how threading works in the JVM.

    Threads in the JVM work on the interrupted model. You can't force a thread to stop for the reasons stated above, but you can request a thread to be interrupted. Its up to the author of the thread to respond to that request.

    Any thread can request any other thread to shutdown by simply calling: threadIWantToKill.interrupt(). That sets the interrupt flag on it. When that thread enters a blocking call or tries to wait on a lock like Thread.sleep(), or Object.wait() an InterruptedException will be thrown. That's why you shouldn't try catch and ignore those. A descent run() loop should be:

    try {
    while( !Thread.currentThread().isInterrupted() ) {
    // do your business here
    }
    } catch( InterruptedException ex ) {
    logger.info("Thread shutting down requested.");
    } finally {
    // clean up any mess here.
    }

    From the comments on this thread its clear most Java developers have no clue about how to cleanly stop threads.

    ReplyDelete
  8. Oh an the Executor framework suggestion doesn't shield you from the rules of threading either. You can still get an InterruptedException thrown inside the Runnable you created because ITS RUNNING IN A THREAD. If you swallow that InterruptedException you're going to prevent the Executor framework from shutting down.

    ReplyDelete
  9. @chubbard , Thanks for your comment.I guess that's why Stop() method of Thread was deprecated because it leaves locks open. Interrupting is also a possible solution.

    ReplyDelete
  10. I guess killing a thread has same meaning as stopping a thread as you can not restart a thread which is stopped in java. natural way of stopping thread is let thread come out of its run() method which as suggest can be used with an exit flag, make sure it should be volatile to prevent compiler or JVM optimization in terms of caching or reordering. here is an example of stopping thread in natural way. By the way if you are working in a project I suggest using Executor framework. Executor can better manage thread and free application code from doing thread management. ExecutorService provides shutdown() method to stop Executors which will stop all running thread on pool. It also provides query method to see if Executor has been terminated or still shutting down.

    ReplyDelete
  11. Rick, you said that ExecutorService provides thread management. On the other hand, the same ExecutorService do not provide any option to stop a thread! You can only shutdown the service which stops all threads. I also read about using Future to stop threads, any ideas!

    ReplyDelete
  12. ExecutorService returns the handle to each thread in the reference of Future. Calling Future.cancel(true) can stop the running thread.

    ReplyDelete
  13. Calling run makes the process run in the same thread, shouldn't you be calling start here?

    ReplyDelete
  14. @Anonymous, Yes Indeed, but in this code we have not even started the thread, it just shows the code to stop the thread, the test part is not included. In order to test the code, you need to create object of Runner class and then need to call start() method on that. That will make you run the code inside run() method on it's own thread, now to stop the thread, just call the exit() method on same Runner object. let me know if you face any problem.

    ReplyDelete
  15. I have been wondering why isn't there a method to kill a waiting, sleeping or a non running thread. Is there anyway we can do that?

    ReplyDelete
  16. if we use stop() method then thread will get stop.
    But stop() is deprecated then what is recommended way to stop thread ?

    ReplyDelete
  17. Hello @Anonymous, the whole article is about that. Yes, you cannot use stop() method anymore, because its deprecated and not safe but you can use a boolean, must be volatile though, to exit from the Runnable loop i.e. run method, that's the only safe way to stop a thread in Java.

    ReplyDelete
  18. Another way is to using interrupt() method to stop the thread.

    ReplyDelete