Monday 15 May 2017

Sleep, wait, yield and join method in Java Thread

Hello Guys !!! Hope you all are doing well. 
Today I am going to discuss sleep, wait, yield and join method uses in java Thread.
The difference between wait and sleep or the difference between sleep and yield in Java are one of the popular core Java interview questions.
Three methods which can be used to pause a thread in Java is :-
  • wait()
  • sleep() and
  • join()

The key difference between wait() and sleep() :-

  1. wait() is used for inter-thread communication while sleep() is used to pause the current thread for a short duration.
  2. when a thread calls the wait() method, it releases the monitor or lock it was holding on that object, but when a thread calls the sleep() method, it never releases the monitor(even if it is holding).
  3. wait() method in Java should be called from synchronized method or block while there is no such requirement for sleep() method
  4. Thread.sleep() method is a static method and applies on current thread, while wait() is an instance specific method and only got wake up if some other thread calls notify method on same object.
  5. in the case of sleep(), sleeping thread immediately goes to Runnable state after waking up while in the case of wait(), waiting for a thread first acquires the lock and then goes into Runnable state.
  6. wait() method normally use on condition as for example Thread wait until a condition is true while sleep is just to put your thread on sleep for a particular interval.
So based upon your need, if you want to pause a thread for specified duration then use sleep() method and if you want to implement inter-thread communication use wait() method.

Coming back to yield()

  • Yield() method is little different than wait() and sleep().
  • it just releases the CPU hold by Thread to give another thread an opportunity to run.
  • Though it's not guaranteed who will get the CPU.
  • It totally depends upon thread scheduler and it's even possible that the thread which calls the yield() method gets the CPU again. Hence, it's not reliable to depend upon yield() method, it's just on best effort basis.

Differences

sleep() 
  • causes the thread to definitely stop executing for a given amount of time
  • if no other thread or process needs to be run, the CPU will be idle (and probably enter a power saving mode).
yield() 
  • method pauses the currently executing thread temporarily for giving a chance to the remaining waiting threads of the same priority to execute. 
  • If there is no waiting thread or all the waiting threads have a lower priority then the same thread will continue its execution. 
  • The yielded thread when it will get the chance for execution is decided by the thread scheduler whose behavior is vendor dependent.

Now coming to join()

The join() method is used to hold the execution of currently running thread until the specified thread is dead(finished execution).

As for example :- t1 and t2 are two threads , t2.join() is called then t1 enters into wait state until t2 completes execution. Then t1 will into runnable state then our specialist JVM thread scheduler will pick t1 based on criteria.

Why we use join() method?

In normal circumstances we generally have more than one thread, thread scheduler schedules the threads, which does not guarantee the order of execution of threads. So we can use join() to wait for a thread to complete its work.

In simple term let say, We have three thread t1, t2 and t3 and we want to run these thread in sequence, one by one the we can go with join.

Please have a look on my example code. For better understanding.

Note:- As per multi threading concept, It is better to use thread to do our work in parallel fashion. There is no benefit for multi threading in serial fashion.
For wait() method follow my previous blog
Thread Sleep Example

package com.sks.softsolution.example1;

public class ThreadSleepExample implements Runnable {
@Override
public void run() {
for (int i = 10; i < 13; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
try {
// thread to sleep for 1000 milliseconds
Thread.sleep(1000);
} catch (Exception e) {
System.out.println(e);
}
}

}

public static void main(String[] args) {
Thread t = new Thread(new ThreadSleepExample());
// this will call run() function
t.start();

Thread t2 = new Thread(new ThreadSleepExample());
// this will call run() function
t2.start();
}
}
Thread Join Example
package com.sks.softsolution.example1;

public class JoinExample {
public static void main(String[] args) {
Thread th1 = new Thread(new MyRunnableClass(), "th1");
Thread th2 = new Thread(new MyRunnableClass(), "th2");
Thread th3 = new Thread(new MyRunnableClass(), "th3");
// Start first thread immediately
th1.start();
/* Start second thread(th2) once first thread(th1)
* is dead
*/
try {
th1.join();
} catch (InterruptedException ie) {
ie.printStackTrace();
}
th2.start();
/* Start third thread(th3) once second thread(th2)
* is dead
*/
try {
th2.join();
} catch (InterruptedException ie) {
ie.printStackTrace();
}
th3.start();
// Displaying a message once third thread is dead
try {
th3.join();
} catch (InterruptedException ie) {
ie.printStackTrace();
}
System.out.println("All three threads have finished execution");
}
}
package com.sks.softsolution.example1;

public class MyRunnableClass implements Runnable{
@Override
public void run() {
Thread t = Thread.currentThread();
System.out.println("Thread started: "+t.getName());
try {
Thread.sleep(4000);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
System.out.println("Thread ended: "+t.getName());
}

}

Thread Yield() example

package com.sks.softsolution.example1;

import java.util.ArrayList;
import java.util.List;

public class MyThreadYield {

    public static void main(String[] args) {

        List<ExmpThread> list = new ArrayList<ExmpThread>();

        for (int i = 0; i < 3; i++) {
            ExmpThread et = new ExmpThread(i + 5);
            list.add(et);
            et.start();
        }

        for (ExmpThread et : list) {
            try {
                et.join();
            } catch (InterruptedException ex) {
            }
        }
    }
}
package com.sks.softsolution.example1;

public class ExmpThread extends Thread {

    private int stopCount;

    public ExmpThread(int count) {
        this.stopCount = count;
    }

    public void run() {
        for (int i = 0; i < 50; i++) {
            if (i % stopCount == 0) {
                System.out.println("Stoping thread: " + getName());
                yield();
            }
        }
    }

}
Thanks!!! Happy Coding !!!! Please put your comment.

1 comment:

  1. hello,
    i just want to say that you have clearly mention the process very clearly and i also found it is very much easy to understand. keep sharing.

    iphone app development company in chennai

    ReplyDelete

Build a Custom Kernel Module for Android

Hi Guys!!!Hope you are doing well !!!. Today I will describe how you can write a custom kernel module(Hello world) for Android and load it a...