Register Now

Login

Lost Password

Enter your email to reset your password.

BY Author

Java – Synchronization

Sometimes, it is necessary that certain part of a program should be processed by only one thread instead of multiple threads at a time until that part gets completed.

The way to achieve this type of condition is known as synchronization.

In synchronization, the part of the program that needs to be executed by only single thread at a time is synchronized by using keyword synchronized.

Synchronized part of a program may be a method or the part of a method called block.

When synchronized keyword is used for a method or certain part of a method, JVM comes to know that this part should be executed by only one thread at a same.

Thus, JVM allows executing synchronized part of a program by only one thread at a time till that part gets complete.

But there are some conditions that must be satisfied for achieving synchronization.

1) A thread that wants to execute a synchronized part of the program must acquire a monitor (lock) of an object.

A monitor is an object. It can also be called as an object’s lock.

For better understanding, let it be called as a right to access synchronized part of the program.

Once any thread gets a monitor, only that thread is allowed to execute the synchronized part of a program. Other threads wait until executing thread releases the monitor, or they execute non-synchronized part of the program with respect to that object.

2) Synchronization is possible only if the threads belong to the same object (this condition will be explained later with examples).

For understanding synchronization, let’s first see the non-synchronized program and then we will see synchronized program.

Non – Synchronized Example

 class Book
 {
     public void read(String name)
     {
         for(int i=1;i<=5;i++)
         {
             System.out.println("I am reading "+name);
             try
             {
                  Thread.sleep(500);
              }
              catch(InterruptedException e)
              {
                  System.out.println("Exception Caught");
              }
         }
     }
 }

 class ChildThread extends Thread
 {
     Book b;
     String name;
      
     public ChildThread(Book b1,String name1)
     {
         b = b1;
         name = name1;
     }
      
     public void run()
     {
         b.read(name);
     }
 }

 class NonSynchrDemo
 {
     public static void main(String args[])
     {
         Book b = new Book();
         ChildThread t1 = new ChildThread(b,"Java");
         ChildThread t2 = new ChildThread(b,"C-sharp");
         t1.start();
         t2.start();
     }
 }

Output

I am reading Java
I am reading C-sharp
I am reading C-sharp
I am reading Java
I am reading Java
I am reading C-sharp
I am reading C-sharp
I am reading Java
I am reading Java
I am reading C-sharp

Here we can see that read() method is not synchronized therefore threads t1 and t2 execute read method simultaneously on object b.
Thus the output is mixed output.

Synchronized Example

 class Book
 {
     public synchronized void read(String name)
     {
         for(int i=1;i<=5;i++)
         {
             System.out.println("I am reading "+name);
             try
             {
                 Thread.sleep(500);
             }
             catch(InterruptedException e)
             {
                 System.out.println("Exception Caught");
             }
         }
     }
 }

 class ChildThread extends Thread
 {
     Book b;
     String name;
      
     public ChildThread(Book b1,String name1)
     {
         b = b1;
         name = name1;
     }
      
     public void run()
     {
         b.read(name);
     }
 }

 class SynchrDemo
 {
     public static void main(String args[])
     {
         Book b = new Book();
         ChildThread t1 = new ChildThread(b,"Java");
         ChildThread t2 = new ChildThread(b,"C-sharp");
         t1.start();
         t2.start();
     }
 }

Output

I am reading Java
I am reading Java
I am reading Java
I am reading Java
I am reading Java
I am reading C-sharp
I am reading C-sharp
I am reading C-sharp
I am reading C-sharp
I am reading C-sharp

                                                                                 OR

I am reading C-sharp
I am reading C-sharp
I am reading C-sharp
I am reading C-sharp
I am reading C-sharp
I am reading Java
I am reading Java
I am reading Java
I am reading Java
I am reading Java

Now in this program, we have just made a small change in read() method with respect to previous non-synchronized example, that is we have used synchronized keyword in its declaration. Therefore we get the result as above.

Using synchronized keyword in method declaration means we have synchronized the method. Therefore that method can be executed by only one thread at a time.

We have created two threads called t1 t2 of class ChildThread. If t1 got first chance to execute read() method, then t2 has to wait until t1’s work gets completed. And if t2 got first chance to execute read() method then t1 has to wait until t2’s work gets completed.

Note

Synchronization is possible only when threads belong to the same object.

Let’s check what happens if two threads of different objects are executing synchronized method.

Example

 class Book
 {
     public synchronized void read(String name)
     {
         for(int i=1;i<=5;i++)
         {
             System.out.println("I am reading "+name);
             try
             {
                 Thread.sleep(500);
             }
             catch(InterruptedException e)
             {
                 System.out.println("Exception Caught");
             }
         }
     }
 }

 class ChildThread extends Thread
 {
     Book b;
     String name;
      
     public ChildThread(Book b1,String name1)
     {
         b = b1;
         name = name1;
     }
      
     public void run()
     {
         b.read(name);
     }
 }

 public class SynchroDemo2
 {
     public static void main(String args[])
     {
         Book b1 = new Book();
         Book b2 = new Book();
         ChildThread t1 = new ChildThread(b1,"Java");
         ChildThread t2 = new ChildThread(b2,"C-sharp");
         t1.start();
         t2.start();
     }
 }

Output

I am reading Java
I am reading C-sharp
I am reading C-sharp
I am reading Java
I am reading Java
I am reading C-sharp
I am reading C-sharp
I am reading Java
I am reading C-sharp
I am reading Java

Here we can see that even though read method is synchronized, an output is same as the previous non-synchronized example because it is executed simultaneously by two threads belonging to two different objects.

Now let’s look in detail that what does it actually means.

If any thread wants to execute synchronized method or a synchronized block with respect to the particular object, it must acquire monitor of that object.

Once that thread acquires a monitor, it is allowed to execute synchronized method or a block with respect to that object.

At that time, no any other thread of that same object is allowed to execute the same synchronized method or a block as well as any other synchronized method or a block with respect to that particular object.

So other threads of that object wait till they get a monitor.

At that time, those waiting threads of that object are allowed to execute any other non-synchronized method or block because it does not require monitor of any object.

But now there is some contradiction.

When any thread is executing some synchronized method by acquiring monitor of a specific object, at the same time thread having a monitor of another object can execute the same synchronized method because normal synchronization is independent of objects.

For better understanding let’s see diagram and its explanation below.

Java Programming Language Thread Synchronization Process in Multithreading

Consider a class Book having synchronized method read1() and non-synchronized method read2().

Two objects of Book type are created and referred by b1 b2 respectively.

Threads t1t2 t3 are associated with Book object b1 and threads t4t5 t6 are associated with Book object b2.

Consider t1 has acquired monitor of object b1 and executing synchronized method read1() with respect to b1.

At that time other threads (t2 t3) of object b1 are not allowed to execute synchronized method read1() as well as any other synchronized method (if available) with respect to b1 because they do not have a monitor of object b1.

So (t2 t3) wait for getting a monitor of object b1. But at that time they can execute non-synchronized method read2() or any other non-synchronized method (if available) with respect to b1.

Since normal synchronization is independent of objects, thread t4 is allowed to execute same synchronized method read1() with respect to b2, at the same time when thread t1 is executing method read1() with respect to b1.

But now threads t5 t6 are not allowed to execute any synchronized method with respect to b2, because monitor of b2 is already acquired by thread t4.

So till they get a monitor of object b2 after releasing by thread t4, they should wait, or at that time they can execute any non-synchronized method with respect to object b2.

 

Leave a reply