In a thread lifecycle it can have one of the following states mentioned below. I have already explained Thread Life Cycle and basics of thread including Daemon Threads.
Now let see inside the thread states and how to achieve them .
- NEW : A thread has not started yet.
- RUNNABLE : Thread is running state but it can be in state of waiting.
- BLOCKED : Thread is waiting to acquire monitor lock to enter into a synchronized block/method after calling
Object.wait()
- WAITING : A thread is in waiting state due to calling one of the following methods
- Object.wait() : It causes current thread to wait until it been notified by method
notifyAll().
- Object.join() : Waits for current thread to die.
- LockSupport.park : Disables the current thread for thread scheduling purposes unless the permit is available.
- Object.wait() : It causes current thread to wait until it been notified by method
- TIMED_WAITING : Current thread is waits for another thread for specified time to perform the aciton.
- Thread.sleep (long timeInMilliSecond) : Makes current thread to cease the execution for specified time.
- Object.wait (long timeInMilliSecond) : * Causes current thread to wait for specified time until time elapsed or get notified by
notify()
ornotifyAll()
.* - Thread.join (long millis) : Current thread waits for specified time to die the thread.
- LockSupport.parkNanos (long nanoSeconds) : Disables the current thread for thread scheduling purposes, for up to the specified waiting time, unless the permit is available.
- LockSupport.parkUntil ()
- TERMINATED : When thread completed its execution.
Also, how to set Thread Priority
NEW, RUNNING and TERMINATED
public class ThreadStates {
public static void main(String []args) throws Exception{
MyThreads firstObj = new MyThreads( 0);
MyThreads secondObj = new MyThreads(1000);
Thread t1 = new Thread(firstObj, "firstThread");
Thread t2 = new Thread(secondObj, "secondThread");
System.out.println(t1.getName() +" "+ t1.getState());
System.out.println(t2.getName() +" "+ t2.getState());
t1.start();
t2.start();
Thread.sleep(2000);
System.out.println(t1.getName() +" "+ t1.getState());
System.out.println(t2.getName() +" "+ t2.getState());
}
}
class MyThreads implements Runnable {
long sleeptime;
MyThreads(long sleeptime){
this.sleeptime = sleeptime;
}
@Override
public void run() {
for(int i=0; i<=5; i++){
System.out.println(Thread.currentThread().getName() + " " + i);
try {
Thread.sleep(sleeptime);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
--- Output--
firstThread NEW
secondThread NEW
secondThread 0
firstThread 0
firstThread 1
firstThread 2
firstThread 3
firstThread 4
firstThread 5
secondThread 1
secondThread 2
firstThread TERMINATED
secondThread TIMED_WAITING (due to Thread.sleep(time) call)
secondThread 3
secondThread 4
secondThread 5
WAITING and TIMED_WAITING due to wait() wait(timeGiven) :
When wait() is called on a Thread, it will keep waiting until notified.
While wait(timeGiven), wait until the timeGiven expired or notified.
public class RunWait {
public static void main(String []args) throws InterruptedException {
WaitDemo waitDemo = new WaitDemo();
Thread t = new Thread(waitDemo, "WaitThread");
t.start();
Thread.sleep(1000);
System.out.println(t.getName()+" checking in main() "+t.getState());
waitDemo.setValue();
}
}
class WaitDemo implements Runnable{
private boolean isValueSet = false;
@Override
public void run() {
synchronized(this){
while(!isValueSet ){
try {
wait(); // Check with wait(1000) for TIMED_WAITING
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println("Got the Value: "+isValueSet);
}
public void setValue(){
synchronized(this){
this.isValueSet = true;
notifyAll();
}
}
}
---
Output
WaitThread checking in main() WAITING
Got the Value: true
BLOCKED : When thread is waiting to enter acquire monitor lock or to enter into synchronized method/block or to enter into Critical Section
public class BlockedDemo {
public static void main(String []args){
BlockedThread blockedThread = new BlockedThread(5);
Thread t1 = new Thread(blockedThread, "t1");
Thread t2 = new Thread(blockedThread, "t2");
t1.start();
t2.start();
System.out.println(t1.getName() +" " +t1.getState());
System.out.println(t2.getName() +" " +t2.getState());
}
}
class BlockedThread implements Runnable {
private int givenVar;
BlockedThread(int givenVar){
this.givenVar = givenVar;
}
@Override
public void run() {
synchronized (this){
try {
Thread.sleep(2000);
givenVar += givenVar;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+" changed value "+ givenVar);
}
}
--------------
Output
t1 TIMED_WAITING
t2 BLOCKED
t1 changed value 10
t2 changed value 20
Observe the output, Thread t2 is in blocked status while t1 is executing. Without synchronized block both thread will read original value of givenVar (try without synchronized block).
Note: Here two threads are working on single object and synchronized block ensuring that only one thread will enter inside the block. This block also known as Critical section.
WAITING and TIMED_WAITING becuase of Thread.join() Thread.join(givenTime)
threadX.join() -- It makes calling thread to wait for threadXto finish.
threadX.join(1000) -- Calling thread will be glued to thread threadX for 1000 miliSeconds and resume after this.
public class ThreadJoinDemo {
public static void main(String []args) throws InterruptedException {
ThreadJoin threadJoin = new ThreadJoin();
Thread t = new Thread(threadJoin);
t.start();
t.join();
System.out.println("in main() method");
}
}
class ThreadJoin implements Runnable{
@Override
public void run() {
System.out.println("Entered run()");
int i = 1;
while(i<5){
i += i;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Finished run()");
}
}
WAITING due to[ LockSupport.park()
Methods park and unpark provide efficient means of blocking and unblocking threads and avoids the the Race condition between one thread is parking another is unparking.
Following is simplest program I code to demonstrate this situation to unpark by other thread.
public class NewPark {
public static void main(String []args) throws InterruptedException {
FIFOMutex fifoMutex = new FIFOMutex();
Thread t1 = new Thread(fifoMutex,"t1");
t1.start();
Thread.sleep(1000);
System.out.println(t1.getName() +" "+ t1.getState());
fifoMutex.unlock(t1); //unPaking thread t1
}
}
class FIFOMutex implements Runnable{
public void lock(){
System.out.println("Parking Thread "+Thread.currentThread().getName());
LockSupport.park();
System.out.println("After unpark "+Thread.currentThread().getName());
}
public void unlock(Thread thread) {
System.out.println("Unparking: "+thread.getName());
LockSupport.unpark(thread);
}
public void run(){
lock();
}
}
---
Output:
Parking Thread t1
t1 WAITING
Unparking: t1
After unpark t1
Setting Thread Priority
You can set priority from 1 (lowest) to 10 (highest) by using thread.setPriority(number) or can use Thread.MAX_PRIORITY, Thread.MIN_PRIORITY. By default thread priority set to 5 that is Thread.NORM_PRIORITY.
Setting priority doesn't guarantee to execute higher priority thread to run first. It just hint the scheduler that this thread has high priority but it's depends on scheduler how to queue the threads.
public class ThreadPriority {
public static void main(String []args) throws InterruptedException {
PriorityThread priorityThread = new PriorityThread();
Thread t1 = new Thread(priorityThread, "Thread1");
Thread t2 = new Thread(priorityThread, "Thread2");
Thread t3 = new Thread(priorityThread, "Thread3");
t3.setPriority(Thread.MAX_PRIORITY);
t2.setPriority(Thread.MIN_PRIORITY);
t1.setPriority(Thread.NORM_PRIORITY);
t1.start();
t2.start();
t3.start();
}
}
class PriorityThread implements Runnable {
@Override
public void run() {
for(int i=0; i < 5 ; i++){
System.out.println(Thread.currentThread().getName() +" "+i);
}
}
}
I hope threads states are clear now, Feel free to comment and share.