Blog_Banner_Asset
    Homebreadcumb forward arrow iconBlogbreadcumb forward arrow iconSoftware Developmentbreadcumb forward arrow iconUltimate Guide to Synchronization in Java

Ultimate Guide to Synchronization in Java

Last updated:
22nd Oct, 2022
Views
Read Time
7 Mins
share image icon
In this article
Chevron in toc
View All
Ultimate Guide to Synchronization in Java

Before we explain synchronization in Java, we must briefly revisit the concept of multithreading. The multithreading feature of Java allows the simultaneous execution of two or more parts of a program for maximum CPU utilization. Each part of such a program is a thread, and threads are lightweight processes within a process. 

Now, multiple threads of a program may try to access the same resources and produce inaccurate results. So, there must be some synchronization to ensure that only one thread has access to resources at a given point in time. 

Check out our free courses to get an edge over the competition.

This guide on what is synchronization in Java will explore the concept of synchronization in detail with examples.

Ads of upGrad blog

Learn Software Development Courses online from the World’s top Universities. Earn Executive PG Programs, Advanced Certificate Programs or Masters Programs to fast-track your career.

What is synchronization in Java?

Java synchronization is the ability to control the access of multiple threads to a shared resource. It is useful when multi-threaded Java programs attempt to access the same resource and produce erroneous outcomes. Using the Java synchronization feature, only a single thread can get to the resource at a given time point. 

Java provides a way to synchronize the task of threads using synchronized blocks that synchronize on the same object and can have only one thread executing inside them at a time. These blocks are marked with the synchronized keyword, blocking any other thread attempting to get into the synchronized block until the thread already inside the block ends its execution and leaves the block.

Check out upGrad’s Advanced Certification in DevOps 

The syntax for Writing a Synchronized Block

The general syntax for writing a synchronized block in Java is as follows:

synchronized( lockObject )

{

// synchronized statements

}

Explore our Popular Software Engineering Courses

In the above syntax, lockObject refers to an object whose lock is related to the synchronized elements. Now, that brings us to the lock concept in Java.

Check out upGrad’s Advanced Certification in Cyber Security

Locks in Java

Synchronization in Java is built around the lock or monitor. Every object has an associated lock. Ideally, a thread that requires access to the fields of an object must first obtain the object’s lock. The lock is a more sophisticated and flexible thread synchronization mechanism than the synchronization block. It is defined inside the java.util.concurrent.lock package containing extensive lock implementations.

In-Demand Software Development Skills

Java Synchronized Method

The purpose of a Java synchronized method is to lock objects for shared resources. Thus, when threads invoke a synchronized method, the method automatically gets the lock for that object and releases it once the thread executes its job.

Here’s an example of a Java synchronized method:

//example of java synchronized method  

class Table{  

 synchronized void printTable(int n){//synchronized method  

   for(int i=1;i<=5;i++){  

     System.out.println(n*i);  

     try{  

      Thread.sleep(400);  

     }catch(Exception e){System.out.println(e);}  

   }  

 }  

}  

class MyThread1 extends Thread{  

Table t;  

MyThread1(Table t){  

this.t=t;  

}  

public void run(){  

t.printTable(5);  

}  

}  

class MyThread2 extends Thread{  

Table t;  

MyThread2(Table t){  

this.t=t;  

}  

public void run(){  

t.printTable(100);  

}  

}  

public class TestSynchronization2{  

public static void main(String args[]){  

Table obj = new Table();//only one object  

MyThread1 t1=new MyThread1(obj);  

MyThread2 t2=new MyThread2(obj);  

t1.start();  

t2.start();  

}  

Read our Popular Articles related to Software Development

Output:

      5

       10

       15

       20

       25

       100

       200

       300

       400

       500

What happens without synchronization?

Now, let’s look at the previous program without synchronization (note the absence of the synchronized keyword).

class Table{  

void printTable(int n){//method not synchronized  

   for(int i=1;i<=5;i++){  

     System.out.println(n*i);  

     try{  

      Thread.sleep(400);  

     }catch(Exception e){System.out.println(e);}  

   }  

 }  

}    

class MyThread1 extends Thread{  

Table t;  

MyThread1(Table t){  

this.t=t;  

}  

public void run(){  

t.printTable(5);  

}  

}  

class MyThread2 extends Thread{  

Table t;  

MyThread2(Table t){  

this.t=t;  

}  

public void run(){  

t.printTable(100);  

}  

}  

class TestSynchronization1{  

public static void main(String args[]){  

Table obj = new Table();//only one object  

MyThread1 t1=new MyThread1(obj);  

MyThread2 t2=new MyThread2(obj);  

t1.start();  

t2.start();  

}  

}  

Output:

       5

       100

       10

       200

       15

       300

       20

       400

       25

       500

As you can see, the output is inconsistent without synchronization. 

Types of Synchronization in Java

To answer what is thread synchronization in Java, we have two types of synchronization available: thread synchronization and process synchronization.

Let’s understand what each means.

Thread synchronization: When multiple threads try to access a shared resource, we must ensure that the resource is used by only one thread at a time. Thread synchronization is the process of allowing only one thread to use the shared resource when multiple threads are trying to use the resource simultaneously.

Process synchronization: It refers to the simultaneous execution of multiple processes to reach a state where the processes commit to an appropriate order of execution. Process synchronization is required when two or more processes cooperate, and the execution of one process affects the other. Thus, process synchronization eliminates the possibility of inaccurate outputs and guarantees the proper execution order.   

Methods of Synchronization in Java

Broadly, there are four methods of synchronization in Java:

  • Synchronized static methods
  • Synchronized instance methods
  • Synchronized block inside static methods
  • Synchronized block inside instance methods

Let’s look at each method of Java synchronization in more detail.

Synchronized static methods

Here, we use the synchronized keyword to mark the static methods in Java. Here’s an example of a Java synchronized static method:

public static MyStaticCounter {

  private static int count = 0;

  public static synchronized void increment(int value) {

    count += value;

  }

}

Synchronized instance methods

When using a synchronized block with instance methods, each object has its synchronized method. Each object can have only one thread that can execute inside a method. If there are multiple objects, a single thread can execute for each object inside the block.

public class MyCounter {

  private int count = 0;

  public synchronized void increment(int value) {

    this.count += value;

  }

  public synchronized void decrement(int value) {

    this.count -= value;

  }

}

Synchronized block inside static methods

Below is an example where we use a synchronized block inside a static method:

public class MyClass {

  public static void print(String message) {

    synchronized(MyClass.class) {

      log.writeln(message);

    }

  }

}

Synchronized block inside instance methods

Instead of synchronizing the entire method, we can use synchronized on a specific block within the method. Below is an example of a synchronized block of code inside an unsynchronized method:

public void increment(int value) {

  synchronized(this) {

    this.count += value;

  }

}

Need for Synchronization in Java

Now that you know what is synchronization in Java, you might be wondering why we use it in the first place. 

The Java synchronized keyword provides functionalities essential for concurrent programming. Here’s how synchronization in Java helps:

  • Java synchronization provides the locking feature to eliminate any race condition among threads and ensure mutually exclusive access to the shared resource.
  • The Java synchronized locking provides both the locking and unlocking features. So, a thread needs to acquire the lock before entering a synchronized method or block.
  • The synchronized keyword prevents the reordering of program statements by the compiler.

Conclusion

Ads of upGrad blog

Summing up, synchronization in Java makes sure that only one thread can access the shared resource at a time. We can make a block or method synchronized using the Java synchronized keyword. When a thread wants to get inside a synchronized block, it must acquire a lock, and after leaving the block, the thread releases the lock. We can use the synchronized keyword either with methods or inside the block of a method.

Do you want to learn the core concepts in Java? The upGrad Executive Post Graduate Programme in Software Development – Specialisation in Full Stack Development course is an online 7 weeks program for beginners who want to explore software development careers. Attend live and interactive classes, practice sessions, and over 35 hours of content delivered by industry leaders to earn a completion certificate from upGrad. 

Sign up today to avail the exclusive upGrad benefits of 24/7 student support and industry networking!

Profile

Pavan Vadapalli

Blog Author
Director of Engineering @ upGrad. Motivated to leverage technology to solve problems. Seasoned leader for startups and fast moving orgs. Working on solving problems of scale and long term technology strategy.

Frequently Asked Questions (FAQs)

1Why do we use synchronized in Java?

The synchronized keyword in Java ensures that only one thread can access the shared resources at a time. It is useful when multithreaded Java programs attempt to access the same resource and produce inaccurate outcomes.

2How is synchronization implemented in Java?

Java implements synchronization using the concept of monitors with only one thread owning a monitor at a given time. When a thread acquires a lock, it gets access to the monitor, and all other threads attempting to get into the locked monitor remain blocked until the first thread leaves the monitor.

3What is a deadlock in Java?

Java deadlock occurs when a thread is waiting for an object lock, but another thread acquires it, and the second thread is waiting for an object lock acquired by the first one. Hence, both the threads wait for each other to release the lock, resulting in a deadlock.