Showing posts with label multithreading. Show all posts
Showing posts with label multithreading. Show all posts

Saturday, 8 October 2016

Yield Vs Join and Sleep Vs Wait

In this post, I am going to discuss about some of the important methods of Thread class and their usage.These methods are also actively asked in interviews.There is very little chance that you would have had the experience of actually using them at the starting level.It is expected from all the interviewee to have basic idea about these methods. Before diving straight into the topic, first let us gather some background information which will help us to understand them better.

Understanding thread priorities and thread scheduling

JVM is a preemptive, priority-based scheduler for threads.Each java thread has a well defined priority.A developer can change the priority of the thread as per the requirements.If the user doesn't set the priority of the thread, a default priority is set for each thread which is same for all in a particular java application.This priority value has its significance in multi threaded environment. It helps the JVM to decide which thread to execute when more than one threads are waiting for a common resource.This is why it is called priority based scheduler. The operating system generally chooses the thread with the highest priority. If any high priority thread is ready for the execution then the scheduler interrupts (preempts) the low priority thread. However, there is a catch, the OS may choose to wait the high priority thread and continue wit the lower priority thread(Ya ya... I know, OS some time can be moody -_- ).

  • Remember that all the threads carry normal priority when a priority is not specified.
  • Priorities can be specified from 1 to 10. 10 being the highest, 1 being the lowest priority and 5 being the normal priority.
  • Remember that the thread with highest priority will be given preference in execution. But there is no guarantee that it will be in running state the moment it starts.
  • It can be assumed that the currently executing thread might have the higher priority when compared to the threads in the pool who are waiting for their chance. However as we have learned this is not 100% guaranteed.
  • It is the thread scheduler which decides what thread should be executed.
  • setPriority(Thread.MIN_PRIORITY) method can be used to set the priority of the thread.
  • Remember that the priorities should be set before the threads start method is invoked.
  • Thread class provides some predefined constants for setting the priority, MIN_PRIORITY,MAX_PRIORITY and NORM_PRIORITY.

sleep() is a method which is used to hold the process for the time you wanted but in case of wait() method thread goes in waiting state and it won’t come back automatically until we call the notify() or notifyAll().

The major difference is that wait() releases the lock or monitor while sleep() doesn’t releases any lock or monitor while waiting. Wait is used for inter-thread communication while sleep is used to introduce pause on execution, generally.

Thread.sleep() sends the current thread into the “Not Runnable” state for some amount of time. The thread keeps the monitors it has acquired — i.e. if the thread is currently in a synchronized block or method no other thread can enter this block or method. If another thread calls t.interrupt() it will wake up the sleeping thread. Note that sleep is a static method, which means that it always affects the current thread (the one that is executing the sleep method). A common mistake is to call t.sleep() where t is a different thread; even then, it is the current thread that will sleep, not the t thread.

object.wait() sends the current thread into the “Not Runnable” state, like sleep(), but with a twist. Wait is called on an object, not a thread; we call this object the “lock object.” Before lock.wait() is called, the current thread must synchronize on the lock object; wait() then releases this lock, and adds the thread to the “wait list” associated with the lock. Later, another thread can synchronize on the same lock object and call lock.notify(). This wakes up the original, waiting thread. Basically, wait()/notify() is like sleep()/interrupt(), only the active thread does not need a direct pointer to the sleeping thread, but only to the shared lock object.


yield() is defined as following in Thread.java.

/**
  * A hint to the scheduler that the current thread is willing to yield its current use of a processor. The scheduler is free to ignore
  * this hint. Yield is a heuristic attempt to improve relative progression between threads that would otherwise over-utilize a CPU.
  * Its use should be combined with detailed profiling and benchmarking to ensure that it actually has the desired effect.
  */

public static native void yield();

A yielding thread tells the virtual machine that it’s willing to let other threads be scheduled in its place. This indicates that it’s not doing something too critical. Note that it’s only a hint, though, and not guaranteed to have any effect at all.

join() method

The join() method of a Thread instance can be used to “join” the start of a thread’s execution to the end of another thread’s execution so that a thread will not start running until another thread has ended. If join() is called on a Thread instance, the currently running thread will block until the Thread instance has finished executing.


Giving a timeout within join(), will make the join() effect to be nullified after the specific timeout. When the timeout is reached, the main thread and taskThread are equally probable candidates to execute. However, as with sleep, join is dependent on the OS for timing, so you should not assume that join will wait exactly as long as you specify.

Like sleep, join responds to an interrupt by exiting with an InterruptedException.

Thursday, 6 October 2016

The Two Synchronized method Problem

The Two Synchronized method Problem.

Problem Statement: A class has two synchronized (non-static)methods M1 and M2. Two different threads T1 and T2 simultaneously trying to access the methods M1 and M2 respectively.
Is is possible?


import java.util.concurrent.TimeUnit;

public class TwoSyncMethods {

 public static void main(String[] args) {
  // TODO Auto-generated method stub

  
  final TwoSyncMethods tsm = new TwoSyncMethods();
  new Thread(new Runnable() {
   
   @Override
   public void run() {
    try {
     tsm.m1();
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
  }, "One").start();
  
   new Thread(new Runnable() {
   
   @Override
   public void run() {
    try {
     tsm.m2();//Calling other synchronized method on same object
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
    
   }
  }, "Two").start();
  
 }

 public synchronized void m1() throws InterruptedException{
  System.out.println("Acquired by "+Thread.currentThread().getName());
  TimeUnit.SECONDS.sleep(2);  
  System.out.println("Released by "+Thread.currentThread().getName());
  
  
 }
  
 public synchronized void m2() throws InterruptedException
        {
   System.out.println("In Sync "+Thread.currentThread().getName());
   TimeUnit.SECONDS.sleep(5);
   System.out.println("In Sync After time out "+Thread.currentThread().getName());
  
 }
 
}

Answer. No,this is not possible.Two different methods can not access the two different synchronized method of the same class simultaneously.

Explanation : Every object has a monitor associated with it.For a thread to enter the synchronized block (also known as critical section), the thread must be the owner of the lock on the monitor. In other words, a thread must acquire a lock on the monitor if it wants to enter critical section.Now, since both the methods are non-static, therefore if they are called on the same object, the 1st thread, requesting the lock on monitor,will acquire the lock on the monitor while the 2nd thread will have to wait for lock to be released.

How to make it possible? As stated above, since same object is used to call both the methods, therefore once the lock is acquired by any one of the threads will cause the other thread to wait. So the solution to this to make two different objects of the class and then call the two methods simultaneously from the different threads using the different objects. This way, both the threads will acquire lock on the monitor of two different objects.


import java.util.concurrent.TimeUnit;

public class TwoSyncMethods {

 public static void main(String[] args) {
  // TODO Auto-generated method stub

  
  final TwoSyncMethods tsm1 = new TwoSyncMethods();
                final TwoSyncMethods tsm2 = new TwoSyncMethods();
  new Thread(new Runnable() {
   
   @Override
   public void run() {
    try {
     tsm1.m1();
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
  }, "One").start();
  
   new Thread(new Runnable() {
   
   @Override
   public void run() {
    try {
     tsm2.m2();//Calling synchronized methods on different objects
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
    
   }
  }, "Two").start();
  
 }

 public synchronized void m1() throws InterruptedException{
  System.out.println("Acquired by "+Thread.currentThread().getName());
  TimeUnit.SECONDS.sleep(2);  
  System.out.println("Released by "+Thread.currentThread().getName());
  
  
 }
  
 public synchronized void m2() throws InterruptedException
        {
   System.out.println("In Sync "+Thread.currentThread().getName());
   TimeUnit.SECONDS.sleep(5);
   System.out.println("In Sync After time out "+Thread.currentThread().getName());
  
 }
 
}

What is the state of the thread waiting for other thread to exit critical section?
Blocked

public class StateCheck {

    public synchronized void m1() {
        try { Thread.sleep(2000); }
        catch (InterruptedException ie) {}
    }

    public synchronized void m2() {
        try { Thread.sleep(2000); }
        catch (InterruptedException ie) {}
    }

    public static void main(String[] args) throws InterruptedException {
        final StateCheck t = new StateCheck();
        Thread t1 = new Thread() { public void run() { t.m1(); } };
        Thread t2 = new Thread() { public void run() { t.m2(); } };

        t1.start();
        Thread.sleep(500);

        t2.start();
        Thread.sleep(500);

        System.out.println(t2.getState());
    }
}
A thread in the blocked state is waiting for a monitor lock to enter a synchronized block/method or reenter a synchronized block/method after calling Object.wait.

Wednesday, 27 July 2016

The HelloWorldThread

Multithreading is one of the most powerful features of Java. Also it is the hottest topic in the Java Interviews at some experience level or even for freshers.This is a must know topic for every Java Developer.In every thread related Java interview, the basic understanding of threads will be tested by asking the wait(),notify() and notifyAll() methods. In the following post, you will get a basic idea about them, followed by some basic interview questions related to them.
The Object class in Java has three final methods that allow threads to communicate about the locked status of a resource. These are :

wait() :It tells the calling thread to give up the lock and go to sleep until some other thread enters the same monitor and calls notify() or notifyAll(). It also has a parameterized version wait(long timeout) which can be used to to pass the amount of time the particular thread should wait before it kicks off again even if the notify() is not called.This method must be called from the synchronized block.If the current thread is interrupted while waiting, it will throw the InterruptedException

notify() : It will wake up a single thread on the monitor associated with the synchronized object. If multiple threads are waiting to acquire the lock, only one of them will be notified.However, the awakened thread will still not be able to execute until and unless the lock is released by this thread.

notifyAll() : Almost similar to notify() in many prospects.It will wake up all the threads that are waiting on the monitor associated with the synchronized object.However, if the awakened threads will try to get the lock on the object, only one thread will be given the lock and the rest of them will again go in the waiting state.The awakened threads will complete their execution in the usual manner.

One common characteristic among the three is that they will throw IllegalMonitorStateException if the current thread is not the owner of this object's monitor.

FAQs

Q. What happens to the lock when the wait method is called?
A. It releases the lock on the monitor.
Q. What is the difference between notify() and notifyAll()?
A. notify() wakes up only one of the threads waiting due to the monitor lock whereas notifyAll() wakes up all the threads.
Q. Can we some how control which thread to wake using notify()?
A. No,this can not be controlled.
Q. Why are these methods in Object class and not in Thread class?
A.Because these methods are used for locking which can be performed on objects and not threads. Apart from threads, these methods are the only way to communicate between the two objects.

Implementation of these methods

Write a Program that will start two threads. One thread will be used to print "Hello" and the other thread should print "World". This should be printed 5 times.

This problem can be treated as a classic Producer-Consumer problem. The HelloPrinter can be considered as Producer and the WorldPrinter can be considered as consumer.Both will take turns to do their job in a synchronized environment.

import java.util.concurrent.TimeUnit;

public class HelloWorldThread
{
 private int helloCount=0;
 private int worldCount=0;
 public final int totalCount=5;// 
 
 public static void main(String[] args) {

  HelloWorldThread hwt = new HelloWorldThread();
  //Sharing same object between threads
  Thread ht = new Thread(new HelloPrinter(hwt));
  Thread wt = new Thread(new WorldPrinter(hwt));

  ht.start();
  wt.start();
  
 }

 public int getHelloCount() {
  return helloCount;
 }

 public void setHelloCount(int helloCount) {
  this.helloCount = helloCount;
 }

 public int getWorldCount() {
  return worldCount;
 }

 public void setWorldCount(int worldCount) {
  this.worldCount = worldCount;
 }

}


class HelloPrinter implements Runnable
{

 HelloWorldThread hwt=null;

 public HelloPrinter(HelloWorldThread hwt) 
 {
  this.hwt=hwt;
 }
 @Override
 public void run() {
  try
  {
   synchronized (hwt) //Critical Section begins
   {
    int helloCount=0;
    while(hwt.getHelloCount() < hwt.totalCount)
    {
     if(hwt.getHelloCount()>hwt.getWorldCount())
     {
      hwt.wait();
     }
     helloCount++;
     System.out.print("Hello ");
     TimeUnit.MILLISECONDS.sleep(200);
     hwt.setHelloCount(helloCount);//Updating the count
     hwt.notify();
    }
   }
  }
  catch(InterruptedException e)
  {
   e.printStackTrace();
  }
 }
}

class WorldPrinter implements Runnable
{

 HelloWorldThread hwt=null;

 public WorldPrinter(HelloWorldThread hwt) 
 {
  this.hwt=hwt;
 }
 @Override
 public void run() {
  try
  {
   synchronized (hwt) //Critical Section begins
   {
    int worldCount=0;
    while(hwt.getWorldCount() < hwt.totalCount)
    {
     if(hwt.getHelloCount()==hwt.getWorldCount())
     {
      hwt.wait();
     }
     worldCount++;
     System.out.println("World!!");
     TimeUnit.SECONDS.sleep(1);
     hwt.setWorldCount(worldCount);//Updating the count
     hwt.notify();
    }
   }
  }
  catch(InterruptedException e)
  {
   e.printStackTrace();
  }
 }
}