In Java programming, it is very common to use threads to perform multi tasks simultaneously. Starting a thread is pretty easy but stopping a thread might be a headache for some programmers, especially when the thread needs to run a task that takes some times.
How to Start a Thread
To start a thread, we simply create a java.lang.Thread object for the object which inherits java.lang.Runnable interface. For example:
public class BigTask implements Runnable { private Thread bigTaskThread; public void startBigTask() { bigTaskThread = new Thread(this); bigTaskThread.start(); } public void run() { // Main entry point for the BigTask's thread } }
When a thread is started, the thread starts calling the java.lang.Runnable’s run()
method. A thread consider stopped when the thread calling method, run()
, is returned.
How to Stop a Thread Correctly
As mentioned above, a thread consider stopped when the thread calling method, run()
, is returned. Although Java does provide a stop()
method to stop the thread but it is not recommended to call the method.
Java also marked the method as deprecated. The main reason a programmer should not call stop()
to stop a thread is that by doing so, it makes a program very difficult to be traced and it is very difficult to know at which point in the codes when the thread has been stopped.
Read more on Why is Thread.stop()
deprecated.
There are three ways that I will normally use to stop a thread correctly:
- Set a flag or a use variable with different states to indicate when a thread should be stopped.
- Interrupt the thread to unblock any blocking calls.
- Combination of method 1 and method 2.
For example:
public class BigTask implements Runnable { private Thread bigTaskThread; public void startBigTask() { bigTaskThread = new Thread(this); bigTaskThread.start(); } public void stopBigTask() { // Interrupt the thread so it unblocks any blocking call bigTaskThread.interrupt(); // Change the states of variable bigTaskThread = null; } // Method 1: Check the state of variable public void run() { Thread currentThread = Thread.currentThread(); while (currentThread == bigTaskThread) { // Running big task } // Thread exits } // Method 2: Interrupt the thread public void run() { while (!Thread.interrupted()) { // Running big task } // Thread exits } // Method 2: Interrupt the thread public void run() { try { // Running big task, calling blocking methods, e.g. read/write file } catch(InterruptedException ex) { } // Thread exits } }
How to Ensure a Thread Has Been Stopped
After stopping a thread, we may also want to ensure the thread is actually stopped before the program can continue to do other things. To do that, we can simply call Thread.join()
at the calling thread and it will wait until the working thread is stopped.
For example:
public class BigTask implements Runnable { private Thread bigTaskThread; public void startBigTask() { bigTaskThread = new Thread(this); bigTaskThread.start(); } public void stopBigTask() { // Interrupt the thread so it unblocks any blocking call bigTaskThread.interrupt(); // Wait until the thread exits try { bigTaskThread.join(); } catch (InterruptedException ex) { // Unexpected interruption ex.printStackTrace(); System.exit(1); } } public void run() { while (!Thread.interrupted()) { // Running big task } // Thread exits } }
It is a good practice that always stops a thread correctly and make sure the thread is fully stopped. Keeping the best practice in mind has always help me to solve multi-threading problems in Java programming.
Leave a Reply