Life cycle of a Thread (Thread States)
NewRunnableRunningNon-Runnable (Blocked)Terminated
A thread can be in one of the five states. According to sun, there is only 4 states in thread life cycle in java new, runnable, non-runnable and terminated. There is no running state.
The life cycle of the thread in java is controlled by JVM. The java thread states are as follows:
- ) New The thread is in new state if you create an instance of Thread class but before the invocation of start() method.
- ) Runnable The thread is in runnable state after invocation of start() method, but the thread scheduler has not selected it to be the running thread.
- ) Running The thread is in running state if the thread scheduler has selected it.
- ) Non-Runnable (Blocked) This is the state when the thread is still alive, but is currently not eligible to run.
- ) Terminated A thread is in terminated or dead state when its run() method exits.
How to create thread
There are two ways to create a thread:By extending Thread classBy implementing Runnable interface
Thread class:
Thread class provide constructors and methods to create and perform operations on a thread. Thread class extends Object class and implements Runnable interface.
Commonly used Constructors of Thread class:Thread()Thread(String name)Thread(Runnable r)Thread(Runnable r,String name)
Runnable interface:
The Runnable interface should be implemented by any class whose instances are intended to be executed by a thread. Runnable interface have only one method named run().
public void run() : is used to perform action for a thread.
Starting a thread : start() method of Thread class is used to start a newly created thread.
It performs following tasks: A new thread starts(with new callstack). The thread moves from New state to the Runnable state. When the thread gets a chance to execute, its target run() method will run.
1) Java Thread Example – by extending Thread class
class Multi extends Thread{
public void run(){
System.out.println("thread is running...");
}
public static void main(String args[]){
Multi t1=new Multi();
t1.start();
}
}
Output:thread is running...
2) Java Thread Example – by implementing Runnable interface
class Multi3 implements Runnable{
public void run(){
System.out.println("thread is running...");
}
public static void main(String args[]){
Multi3 m1=new Multi3();
Thread t1 =new Thread(m1);
t1.start();
}
}
Output:thread is running...
If you are not extending the Thread class,your class object would not be treated as a thread object. So you need to explicitly create Thread class object. We are passing the object of your class that implements Runnable so that your class run() method may execute.
Thread Scheduler in Java
Thread scheduler in java is the part of the JVM that decides which thread should run. There is no guarantee that which runnable thread will be chosen to run by the thread scheduler. Only one thread at a time can run in a single process. The thread scheduler mainly uses preemptive or time slicing scheduling to schedule the threads.
Difference between preemptive scheduling and time slicing
Under preemptive scheduling, the highest priority task executes until it enters the waiting or dead states or a higher priority task comes into existence. Under time slicing, a task executes for a predefined slice of time and then reenters the pool of ready tasks. The scheduler then determines which task should execute next, based on priority and other factors.
Deadlock in java
Deadlock in java is a part of multithreading. Deadlock can occur in a situation when a thread is waiting for an object lock, that is acquired by another thread and second thread is waiting for an object lock that is acquired by first thread. Since, both threads are waiting for each other to release the lock, the condition is called deadlock.
Can we start a thread twice ??
No. After starting a thread, it can never be started again. If you does so, an IllegalThreadStateException is thrown. In such case, thread will run once but for second time, it will throw exception.
Let’s understand it by the example given below:
public class TestThreadTwice1 extends Thread{
public void run(){
System.out.println("running...");
}
public static void main(String args[]){
TestThreadTwice1 t1=new TestThreadTwice1();
t1.start();
t1.start();
}
}
Test it Now
running
Exception in thread "main" java.lang.IllegalThreadStateException
What if we call run() method directly instead start() method ?
Each thread starts in a separate call stack. Invoking the run() method from main thread, the run() method goes onto the current call stack rather than at the beginning of a new call stack. It runs like a normal method, and does not calls the thread stack.
Multithreading in Java
Multithreading in java is a process of executing multiple threads simultaneously. Thread is basically a lightweight sub-process, a smallest unit of processing. Multiprocessing and multithreading, both are used to achieve multitasking. But we use multithreading than multiprocessing because threads share a common memory area. They don’t allocate separate memory area so saves memory, and context-switching between the threads takes less time than process.
Java Multithreading is mostly used in games, animation etc.
Advantages of Java Multithreading
- ) It doesn’t block the user because threads are independent and you can perform multiple operations at same time.
- ) You can perform many operations together so it saves time.
- ) Threads are independent so it doesn’t affect other threads if exception occur in a single thread.
Java Executor Framework for Multithreading
Java executor framework exist from JDK 5 in concurrent package(java.uti.concurrent.Executor). It is used to run the Runnable objects without creating a new thread every time rather it reuses the already created threads from the thread pool. Since creating a thread in java is a very expensive process as there is a memory overhead.
Executors is a utility class that also provides useful methods to work with ExecutorService, ScheduledExecutorService, ThreadFactory, and Callable classes through various factory methods.
Example: Java executor framework
A Runnable class, named WorkerThread.java:
package com.test.threadpool;
public class WorkerThread implements Runnable {
private String command;
public WorkerThread(String s){
this.command=s;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+
" Start. Command = "+command);
processCommand();
System.out.println(Thread.currentThread().getName()+
" End.");
}
private void processCommand() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public String toString(){
return this.command;
}
}
Below is the main class with Thread pool created using Executors Framework
In the above program, we are creating a fixed size thread pool of 5 worker threads. Then we are submitting 10 jobs to this pool, since the pool size is 5, it will start working on 5 jobs and other jobs will be in wait state, as soon as one of the job is finished, another job from the wait queue will be picked up by worker thread and get’s executed.
package com.programmertoday.threadpool;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SimpleThreadPool {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
Runnable worker = new WorkerThread("" + i);
executor.execute(worker);
}
executor.shutdown();
while (!executor.isTerminated()) {
}
System.out.println("Finished all threads");
}
}
OUTPUT :
pool-1-thread-2 Start. Command = 1
pool-1-thread-4 Start. Command = 3
pool-1-thread-1 Start. Command = 0
pool-1-thread-3 Start. Command = 2
pool-1-thread-5 Start. Command = 4
pool-1-thread-4 End.
pool-1-thread-5 End.
pool-1-thread-1 End.
pool-1-thread-3 End.
pool-1-thread-3 Start. Command = 8
pool-1-thread-2 End.
pool-1-thread-2 Start. Command = 9
pool-1-thread-1 Start. Command = 7
pool-1-thread-5 Start. Command = 6
pool-1-thread-4 Start. Command = 5
pool-1-thread-2 End.
pool-1-thread-4 End.
pool-1-thread-3 End.
pool-1-thread-5 End.
pool-1-thread-1 End.
Finished all threads
Summary
In this article we learnt about Java Multithreading, life cycle of a thread, how to create a thread, thread schedulers, executor framework and more.
Hope you liked the article !