Synchronization in Java

Introduction 

 
The following article contains one of the most important concepts of Java, Synchronisation in Java, along with simple examples to get a proper idea of the concept.
  

Synchronization in Java

 
Basically Synchronization in Java is the process of allowing the threads to execute one after the other. It controls the access of multiple threads to a shared resource.
  
Java is a multithreaded language where multiple threads can run in parallel to execute the program. In a multithreaded environment, there is a necessity for synchronization of Java objects that share common resources concurrently. When two or more threads start within a program then there may be a situation of inconsistent results due to concurrency issues since multiple threads try to access the same resource at the same time. 
 
Suppose multiple threads try to do a write operation; that may corrupt the data because one of the threads may overwrite the data or while one of the threads is opening the file at a time and another is closing the same file at the same time. 
 
So there is a need for synchronization that ensures that only one thread can access the resource at a given time. This can be done by using the concept called monitor. In Java, each object is associated with a monitor that a thread can lock or unlock. Only one thread can hold or lock at a time on a monitor. 
 
The following is the syntax of a synchronization block:
  1. synchronized(object identifier)  
  2. {  
  3.     // access shared variables and other shared resources  
  4. }   
An object identifier is a reference to an object whose lock associates with the monitor that the synchronized statement represents.
  
The Synchronized keyword provides locking that ensures the mutual exclusion access to shared resources and prevents the data race. 
 
When a thread invokes a synchronization method, it automatically acquires a lock for that object and releases it when the method returns the chance to the next thread. 
 
Example without Synchronization 
 
Now let's see an example of multithreading without synchronization and analyse what happens without synchronization.
  1. class Serial  
  2. {  
  3.  void serialDisplay(int n)  
  4.  {  
  5.   // method is not synchronized  
  6.   for (int i = 1; i <= 5; i++)  
  7.   {  
  8.    System.out.println("Thread " + i + " is :" + (n * i));  
  9.    try  
  10.    {  
  11.     Thread.sleep(300);  
  12.    }   
  13.    catch (Exception e)  
  14.    {  
  15.     System.out.println("Thread interrupted" + e);  
  16.    }  
  17.   }  
  18.  }  
  19. }  
  20. class Thread1 extends Thread  
  21. {  
  22.  Serial s;  
  23.  Thread1(Serial s)  
  24.  {  
  25.   this.s = s;  
  26.  }  
  27.  public void run()  
  28.  {  
  29.   s.serialDisplay(10);  
  30.  }  
  31. }  
  32. class Thread2 extends Thread  
  33. {  
  34.  Serial s;  
  35.  Thread2(Serial s)   
  36.  {  
  37.   this.s = s;  
  38.  }  
  39.  public void run()  
  40.  {  
  41.   s.serialDisplay(50);  
  42.  }  
  43.  class ThreadTest  
  44.  {  
  45.   public static void main(String args[])  
  46.   {  
  47.    Serial no = new Serial();  
  48.    Thread1 t1 = new Thread1(no);  
  49.    Thread2 t2 = new Thread2(no);  
  50.    t1.start();  
  51.    t2.start();  
  52.    // wait for threads to end  
  53.    try  
  54.    {  
  55.     t1.join();  
  56.     t2.join();  
  57.    }   
  58.    catch (Exception e)  
  59.    {  
  60.     System.out.println("Interrupt occurred" + e);  
  61.    }  
  62.   }  
  63.  }   
Output
  
Thread 1 is :10 
Thread 1 is :50 
Thread 2 is :100 
Thread 2 is :20 
Thread 3 is :30 
Thread 3 is :150 
Thread 4 is :200 
Thread 4 is :40 
Thread 5 is :250 
Thread 5 is :50
 
Here, you can see that without synchronization method the output result is inconsistent
  
This can produce a different result every time the program is run.
  
Example with Synchronization
  
Now let's have a look at the same example explained above with a slight change, now with synchronization and watch the difference between the two.
  
Just make change in the following line of code:
 
synchronized void serialDisplay(int n) 
{
    // method is now synchronized
}
 
Add the keyword synchronization before void serialDisplay(int n) as shown above and you will get the synchronised output that is shown below.
  
Output after making change
 
Thread 1 is :10 
Thread 2 is :20 
Thread 3 is :30 
Thread 4 is :40 
Thread 5 is :50 
Thread 1 is :50 
Thread 2 is :100 
Thread 3 is :150 
Thread 4 is :200 
Thread 5 is :250 
 
Now you can see the threading that is synchronized so properly that it looks like every thread gets the chance to execute one after the other.