«Back to Home

Core Java

Topics

Introduction Of Synchronization In Java

Synchronization

In Java, Synchronization is the capacity to control the access of the multiple threads to any shared resource. It is a good option, when we want to allow only one thread to access the shared resource.
 
Why we use synchronization?

It is used to prevent thread interference. It is used to prevent consistency problem.
 
Types of Synchronization

There are two kinds of synchronization, which are,
  • Process Synchronization

  • Thread Synchronization
Since Java uses thread synchronization only, so we are going to discuss it only.
 
Thread Synchronization

There are two kinds of thread synchronization.
  1. Mutual Exclusive

    • Synchronized method.

    • Synchronized block.

    • Static synchronization.

  2. Cooperation (Inter-thread communication)
Mutual Exclusive

Mutual Exclusive helps to keep the threads from a interfere with one another as sharing data.
This can be done by three ways, which are,
  • By synchronized method

  • By synchronized block

  • By static synchronization
Lock Concept

Synchronization is built around an internal entity called as the lock or monitor. All objects have a lock associated with it. By rule, a thread that needs consistent access to an object's fields has to get the object's lock before accessing them and release the lock, when it's done with them. Since Java 5, the package java.util.concurrent.locks contains many lock implementations.
 
Let’s see an example without synchronization.
 
Code
  1. class A {  
  2.     void print(int n) {  
  3.         for (int i = 1; i <= 5; i++) {  
  4.             System.out.println(n * i);  
  5.             try {  
  6.                 Thread.sleep(1000);  
  7.             } catch (Exception e) {  
  8.                 System.out.println(e);  
  9.             }  
  10.         }  
  11.     }  
  12. }  
  13. class MyThread1 extends Thread {  
  14.     A a;  
  15.     MyThread1(A a) {  
  16.         this.a = a;  
  17.     }  
  18.     public void run() {  
  19.         a.print(1);  
  20.     }  
  21. }  
  22. class MyThread2 extends Thread {  
  23.     A a;  
  24.   
  25.     MyThread2(A a) {  
  26.         this.a = a;  
  27.     }  
  28.     public void run() {  
  29.         a.print(100);  
  30.     }  
  31. }  
  32. public class SynchronizationExample {  
  33.     public static void main(String args[]) {  
  34.         A obj = new A();  
  35.         MyThread1 t1 = new MyThread1(obj);  
  36.         MyThread2 t2 = new MyThread2(obj);  
  37.         t1.start();  
  38.         t2.start();  
  39.     }  
  40. }  

1
2

Output

3
 
In the example, mentioned above, there is no synchronization. Thus output is inconsistent.
 
Synchronized method

If we create any method as synchronized, it is called as synchronized method. Synchronized method locks an object for any shared resource.
 
When a thread calls a synchronized method, it automatically gets the lock for that object and frees it when the thread completes its task.
 
Let’s see an example of synchronized method, given below.
 
Code
  1. class A {  
  2.     synchronized void print(int n) {  
  3.         for (int i = 1; i <= 5; i++) {  
  4.             System.out.println(n * i);  
  5.             try {  
  6.                 Thread.sleep(1000);  
  7.             } catch (Exception e) {  
  8.                 System.out.println(e);  
  9.             }  
  10.         }  
  11.     }  
  12. }  
  13. class MyThread1 extends Thread {  
  14.     A a;  
  15.     MyThread1(A a) {  
  16.         this.a = a;  
  17.     }  
  18.     public void run() {  
  19.         a.print(1);  
  20.     }  
  21. }  
  22.   
  23. class MyThread2 extends Thread {  
  24.     A a;  
  25.     MyThread2(A a) {  
  26.         this.a = a;  
  27.     }  
  28.     public void run() {  
  29.         a.print(100);  
  30.     }  
  31. }  
  32. public class SynchronizationExample {  
  33.     public static void main(String args[]) {  
  34.         A obj = new A();  
  35.         MyThread1 t1 = new MyThread1(obj);  
  36.         MyThread2 t2 = new MyThread2(obj);  
  37.         t1.start();  
  38.         t2.start();  
  39.     }  
  40. }  

4
5

Output

6

Let’s see an example of synchronized method with annonymous class.
 
Code
  1. class A {  
  2.     synchronized void print(int n) {  
  3.         for (int i = 1; i <= 5; i++) {  
  4.             System.out.println(n * i);  
  5.             try {  
  6.                 Thread.sleep(1000);  
  7.             } catch (Exception e) {  
  8.                 System.out.println(e);  
  9.             }  
  10.         }  
  11.     }  
  12. }  
  13. public class SynchronizationExample {  
  14.     public static void main(String args[]) {  
  15.         final A obj = new A();  
  16.         Thread t1 = new Thread() {  
  17.             public void run() {  
  18.                 obj.print(1);  
  19.             }  
  20.         };  
  21.         Thread t2 = new Thread() {  
  22.             public void run() {  
  23.                 obj.print(100);  
  24.             }  
  25.         };  
  26.         t1.start();  
  27.         t2.start();  
  28.     }  
  29. }  
7
Output

8

In the program mentioned above, we create two threads with annonymous class. Thus, less coding is required.
 
Summary

Thus, we learnt, Java synchronization is the capacity to control the access of multiple threads to any shared resource and also learnt why we need to use it in Java.