Synchronization in Java

In this Java synchronization tutorial we will see what is meaning of Synchronization in Java, Why do we need Synchronization in java, what is java synchronized keyword, example of using java synchronized method and blocks and important points about synchronization in Java.

Synchronization 
Synchronization is the capability of control the access of multiple threads to any shared resource. Synchronization is better in case we want only one thread can access the shared resource at a time.

Synchronization in Java is an important concept since Java is a multi-threaded language where multiple threads run in parallel to complete program execution. In multi-threaded environment synchronization of java object or synchronization of java class becomes extremely important. Synchronization in Java is possible by using java keyword "synchronized" and "volatile”. Concurrent access of shared objects in Java introduces to kind of errors: thread interference and memory consistency errors and to avoid these errors you need to properly synchronize your java object to allow mutual exclusive access of critical section to two threads.

Why use Synchronization?
The synchronization is mainly used to

  1. To prevent thread interference.
  2. To prevent consistency problem.

If your code is executing in multi-threaded environment you need synchronization for objects which are shared among multiple threads to avoid any corruption of state or any kind of unexpected behavior. Synchronization in Java will only be needed if shared object is mutable. if your shared object is read only or immutable object you don't need synchronization despite running multiple threads. Same is true with what threads are doing with object if all the threads are only reading value then you don't require synchronization in java. JVM guarantees that Java synchronized code will only be executed by one thread at a time.

1) synchronized keyword in java provides locking which ensures mutual exclusive access of shared resource and prevent data race.
2) synchronized keyword also prevent reordering of code statement by compiler which can cause subtle concurrent issue if we don't use synchronized or volatile keyword.
3) synchronized keyword involve locking and unlocking. before entering into synchronized method or block thread needs to acquire the lock at this point it reads data from main memory than cache and when it release the lock it flushes write operation into main memory which eliminates memory inconsistency errors.

Types of Synchronization:
There are two types of synchronization

  1. Process Synchronization
  2. Thread Synchronization

Here, we will discuss only thread synchronization.
Thread Synchronization:
There are two types of thread synchronization mutual exclusive and inter-thread communication.

  1. Mutual Exclusive
    • Synchronized method.
    • Synchronized block.
    • static synchronization.
  2. Cooperation (Inter-thread communication)
Mutual Exclusive
Mutual Exclusive helps keep threads from interfering with one another while sharing data. This can be done by three ways in java:
  1. by synchronized method
  2. by synchronized block
  3. by static synchronization
Understanding the concept of Lock
Synchronization is built around an internal entity known as the lock or monitor.Every object has an lock associated with it. By convention, a thread that needs consistent access to an object's fields has to acquire the object's lock before accessing them, and then release the lock when it's done with them.
From Java 5 the package java.util.concurrent.locks contains several lock implementations.
Understanding the problem without Synchronization:
In this example, there is no synchronization, so output is inconsistent. Let's see the example:

class First
{
   public void display(String msg)
   {
      System.out.print ("["+msg);
      try
      {
         Thread.sleep(500); 
      }
      catch(InterruptedException e)
      {
         e.printStackTrace();
      }
      System.out.println ("]");
   }
}

class Second extends Thread
{
     String msg;
     First fobj;
     Second (First fp,String str)
     {
        fobj = fp;
        msg = str;
        start();
     }
     public void run()
     {
        fobj.display(msg);
     }
}

public class WithoutSyncDemo
{
    public static void main (String[] args) 
    {
       First fnew = new First();
       Second ss  = new Second(fnew, "welcome");
       Second ss1 = new Second (fnew,"to");
       Second ss2 = new Second(fnew, "dineshonjava.com");
    }
}
Output:

In the above program, object fnew of class First is shared by all the three running threads(ss, ss1 and ss2) to call the shared method(void display). Hence the result is unsynchronized and such situation is called Race condition.

Solution by synchronized method:
  1. If you declare any method as synchronized, it is known as synchronized method.
  2. Synchronized method is used to lock an object for any shared resource.
  3. When a thread invokes a synchronized method, it automatically acquires the lock for that object and releases it when the method returns.
class First
{
   public synchronized void display(String msg) //synchronized method
   {
      System.out.print ("["+msg);
      try
      {
         Thread.sleep(500); 
      }
      catch(InterruptedException e)
      {
         e.printStackTrace();
      }
      System.out.println ("]");
   }
}

class Second extends Thread
{
     String msg;
     First fobj;
     Second (First fp,String str)
     {
        fobj = fp;
        msg = str;
        start();
     }
     public void run()
     {
        fobj.display(msg);
     }
}

public class WithoutSyncDemo
{
    public static void main (String[] args) 
    {
       First fnew = new First();
       Second ss  = new Second(fnew, "welcome");
       Second ss1 = new Second (fnew,"to");
       Second ss2 = new Second(fnew, "dineshonjava.com");
    }
}
output:

Solution by synchronized block:
  1. If you declare block of shared lines as synchronized, it is known as synchronized block.
  2. Synchronized block is used to lock an object for any shared resource.
  3. When a thread invokes a code within synchronized block, it automatically acquires the lock for that object and releases it when the synchronized block executed.
class First
{
   public void display(String msg) 
   {
      System.out.print ("["+msg);
      try
      {
         Thread.sleep(500); 
      }
      catch(InterruptedException e)
      {
         e.printStackTrace();
      }
      System.out.println ("]");
   }
}

class Second extends Thread
{
     String msg;
     First fobj;
     Second (First fp,String str)
     {
        fobj = fp;
        msg = str;
        start();
     }
     public void run()
     {
        synchronized(fobj){       //Synchronized block
            fobj.display(msg);
        }
     }
}

public class WithoutSyncDemo
{
    public static void main (String[] args) 
    {
       First fnew = new First();
       Second ss  = new Second(fnew, "welcome");
       Second ss1 = new Second (fnew,"to");
       Second ss2 = new Second(fnew, "dineshonjava.com");
    }
}
output:
Synchronized Keyword:
To synchronize above program, we must synchronize access to the shared display() method, making it available to only one thread at a time. This is done by using keyword synchronized with display() method.
synchronized void display (String msg) 



<<Previous <<   || Index ||   >>Next >>


1 comment:

  1. "2) synchronized keyword also prevent reordering of code statement by compiler which can cause subtle concurrent issue if we don't use synchronized or volatile keyword.". what you want to say in this sentence..theme is not clear. please reorder sentence.

    ReplyDelete