Thread’s Life Cycle is an important part of the Java’s Thread’s concepts. Life cycle of thread defines its interaction and behavior with the system and the resources. The programmer needs to understand its knits and bits to avoid any memory leak or a situation where a unknown thread keeps running infinitely eating up resources or creating a deadlock. But to understand the thread’s life cycle its important that you understand the basics of Thread and how to instantiate a thread in different ways. If not I suggest you to read them first and then you can continue with this post.
Thread’s Life Cycle
The Thread’s Life Cycle is important to understand if you want to write a logically correct program. The Thread’s Life cycle is divided into five states. These states are as follows:
The New state is that state where we create an instance of the Thread, but the start method has not been yet called. This means the Thread object is live (has got its place in the heap memory) but the thread is not alive (still has not got its own stack).
The start method has been called on the Thread’s instance and it has got its own stack, but the Thread scheduler has not selected it to run. Here we can say that thread is alive but now its up to Thread’s scheduler to run it. The thread can be brought to Runnable state from New, Running and Blocking/Waiting/Sleeping states.
Scheduler chooses a thread from the Runnable state and starts executing it and called to be in Running state. Now it has become a process. The thread can move out of Running state because of multiple reasons including if Thread scheduler does so.
Thread is now not eligible to run (Not in Running State). Reasons could be – thread is waiting for another thread to finish off, or might be blocked as resource is locked or might be put in sleep state by the programmer as per the code and will wake up as sleep time gets finished.
Thread is no longer alive. Its run method is finished and its no longer a thread of execution, but an object. If you try to call start method on the object again it will give you a runtime exception.
To understand the states and behavior of the thread we have to understand all the external and internal factors which can affect the thread’s execution. One of these factors is Thread Scheduler, which is a part of the JVM and decides at what time thread should run and taken out of the run state. Most of the JVMs use underlying OS’s thread scheduler for scheduling threads. Also one important point is that nothing is guaranteed on the order of thread run.
But we have ways to influence the thread scheduler, which are the methods available from :
- public static void sleep(long millis) throws InterruptedException – It slows down the execution of the thread. It will bring the calling thread to sleep but not to the other threads. It pause the execution for given time period, if interrupted before wake time it throws Interrupted exception. After the sleep time is over it returns to runnable state. Then it is upto JVM to bring it to running state. Thus sleep doesn’t guarantee that after specified time the thread will start. It just guarantees that for specified time thread will not run.
- public static final void join() throws InterruptedException – Current thread stops the execution until the thread it has joined finished its job and no longer alive. Let’s say main thread creates another thread t1 and starts it and then calls t1.join(). It means the main thread joins the t1 thread, and executes(become runnable) only when t1 completes its own execution.
- public final void setPriority(int newPriority) – Thread has priorities usually between 1 to 10. Thread scheduler uses priority while bringing a thread from runnable to running state. The higher priority thread will be preferred than a lower priority thread. If a thread in runnable state has higher priority than running thread, the running thread will be sent back to runnable state and higher priority thread will be chosen to run. Usually running thread has highest or equal priority than the threads in the runnable pool. A thread gets default priority i.e. priority equal to the thread of execution which creates it.
- public static void yield() – It moves the currently running thread to runnable to allow other threads of same priority to get their turn. But it doesn’t guarantee that what it claim to do. It might or might not move current thread to runnable state from running state. Remember it doesn’t move thread to blocking/sleeping/waiting state, but to runnable state from running state.
- public final void wait() throws InterruptedException
- public final void notify()
- public final void notifyAll()
These methods are well understood when you read our post Synchronization and Locks of Java Thread. The life cycle of thread can be managed by all above methods. But you should know that the functionalities provided by the functions are unpredictable. They may or may not be able to alter the state of thread.
Some important facts related to multiple thread execution:
- Each thread will start and run to completion.
- Thread execution is not guaranteed with respect to other threads, but is guaranteed within itself.
- Thread ceases to be thread of execution when run is finished. Thread is dead after that.
- After thread of execution is dead, the Thread object still exists. The Thread object instance can be used to call methods other than start() function.
- Calling start() second time gives IllegalThreadStateExecution. A new Thread can be started only once.
I hope this clears concept regarding life cycle of the thread. In case you have any queries you can comment below or on our Facebook page.