What is the use of Synchronized keyword in Java
Tags: java, tutorial, beginners, threads
Published: 2020-11-16 15:53:04

---
title: "What is the use of Synchronized keyword in Java"
description: "What is the use of Synchronized keyword in Java"
published : true
tags : java, tutorial, beginner, threads
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/7ktvzlz23rcb5vxzd7bo.jpg
canonical_url: https://adityasridhar.com/posts/what-is-the-use-of-synchronized-keyword-in-java
series: Multithreading Series
---

**This post was originally published in [adityasridhar.com](https://adityasridhar.com/posts/what-is-the-use-of-synchronized-keyword-in-java)**

This article will focus on what the synchronized keyword does in Java and when to use it.

In order to understand this article better please go through my article on [Introduction to Multithreading](https://adityasridhar.com/posts/how-to-get-started-with-multithreading-in-java) in case you are new to multithreading in Java.

# What is the use of Synchronized?

Let's take the following code snippet:

```java
public void doSomething(){
    //Execute Logic 1
    //Execute Logic 2
    ......
}
```

Let's say that 2 threads t1 and t2 will be calling **doSomething()** method.

**Here the main thing we care about is that if one thread calls doSomething(), then it needs to finish everything in the method before another thread gets to call doSomething()**.

Basically something like this:

```bash
t1 executes Logic 1
t1 executes Logic 2
t2 executes Logic 1
t2 executes Logic 2
```

or 

```bash
t2 executes Logic 1
t2 executes Logic 2
t1 executes Logic 1
t1 executes Logic 2
```

**But reality is they can run in any order.**.  The below scenario is highly possible:


```bash
t1 executes Logic 1
t2 executes Logic 1
t1 executes Logic 2
t2 executes Logic 2
```

But what if we want to ensure that t1 fully finishes **doSomething()** before t2 starts **doSomething()**?

This is where synchronized comes in. Synchronized ensures that any method or piece of code which is synchronized should be fully completed by one thread before another thread can access that block. 

If we make **doSomething()** synchronized as shown below, then only one thread can access **doSomething()** at a time

```java
public synchronized void doSomething(){
    //Execute Logic 1
    //Execute Logic 2
    ......
}
```

# Different ways of using Synchronized

## Normal Synchronized Method

In this section we will create 3 threads which will print numbers from 0 to 5. 

First let's create a simple utility which will print numbers from 0 to 5:

```java
class PrintUtil {
    public synchronized void printNumbers() {
        for (int i = 0; i <= 5; i++) {
            System.out.println(Thread.currentThread().getName() + ": " + i);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
```

This util has a method called **printNumbers()**. This method prints numbers from 0 to 5 and waits for 100ms after every print. 
The method is marked as **synchronized** so that at any time only one thread can access **printNumbers()** method.

Next let's create a worker which will implement Runnable Interface:

```java
class RunnableWorker implements Runnable {
    PrintUtil pu;
    public RunnableWorker(PrintUtil pu) {
        this.pu = pu;
    }

    @Override
    public void run() {
        pu.printNumbers();
    }
}
```

This is very simple worker which calls the **printNumbers()** method in **PrintUtil** class. 

Finally let's create the Main class which will tie all this together:

```java
public class SynchronizedMethodDemo {
    public static void main(String[] args) {
        PrintUtil pu = new PrintUtil();
        Runnable r = new RunnableWorker(pu);
        Thread t1 = new Thread(r);
        Thread t2 = new Thread(r);
        Thread t3 = new Thread(r);

        t1.start();
        t2.start();
        t3.start();
    }
}
```

The main class creates an instance of PrintUtil.

It then creates 3 threads t1, t2 and t3 by passing the RunnableWorker as an argument and then starts the 3 threads.

The output of the above program is given below:

```bash
Thread-0: 0
Thread-0: 1
Thread-0: 2
Thread-0: 3
Thread-0: 4
Thread-0: 5
Thread-2: 0
Thread-2: 1
Thread-2: 2
Thread-2: 3
Thread-2: 4
Thread-2: 5
Thread-1: 0
Thread-1: 1
Thread-1: 2
Thread-1: 3
Thread-1: 4
Thread-1: 5
```

As seen above, Synchronized has ensured that only when one thread completes printing from 0 to 5, the other thread starts it's execution.

### How does this work ?

In this example the **PrintUtil object instance pu** has a lock. When one thread executes the **printNumbers()** method, it gets the lock from pu. This thread releases the lock only when printNumbers() execution is fully done. The other threads can execute **printNumbers()** only when they get the lock.

Since each thread holds the lock until **printNumbers()** is fully complete, we get the output shown above.

In General the lock is held by the object which calls the synchronized method. In this case that object was **pu**

## Synchronized with Static methods

In this example we use a static method to print numbers from 0 to 5 instead of an instance method.

The Printer Utility code is shown below:

```java
class PrintUtilExample2 {
    public static synchronized void printNumbers() {
        for (int i = 0; i <= 5; i++) {
            System.out.println(Thread.currentThread().getName() + ": " + i);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
```

Here the method is marked as static and synchronized. 

Next let us create the worker. The code for the worker is shown below:

```java
class RunnableWorkerExample2 implements Runnable {
    @Override
    public void run() {
        PrintUtilExample2.printNumbers();
    }
}
```

In this case the worker calls printNumbers() directly using the class name since it is static method.

Finally we have the main class which is shown below:

```java
public class SynchronizedStaticMethodDemo {
    public static void main(String[] args) {
        Runnable r = new RunnableWorkerExample2();
        Thread t1 = new Thread(r);
        Thread t2 = new Thread(r);
        Thread t3 = new Thread(r);

        t1.start();
        t2.start();
        t3.start();
    }
}
```

Here also the main method creates three threads t1, t2 and t3 with argument as RunnableWorkerExample2 and starts the threads.

The output of this code is given below:

```bash
Thread-2: 0
Thread-2: 1
Thread-2: 2
Thread-2: 3
Thread-2: 4
Thread-2: 5
Thread-0: 0
Thread-0: 1
Thread-0: 2
Thread-0: 3
Thread-0: 4
Thread-0: 5
Thread-1: 0
Thread-1: 1
Thread-1: 2
Thread-1: 3
Thread-1: 4
Thread-1: 5
```

Again we can see that each thread completes printing from 0 to 5 before the next thread starts printing.

### How does this work

In case of static methods, the lock is maintained by the PrintUtilExample2 class itself. Rest of the locking mechanism is exactly same as mentioned in the previous section.

## Creating synchronized blocks with custom objects

In this section we will see how to make a block of code synchronized using a custom object.

The Print utility class is shown below:

```java
class PrintUtilExample3 {
    final Object lockObject = new Object();
    public void printNumbers() {
        synchronized(lockObject) {
            for (int i = 0; i <= 5; i++) {
                System.out.println(Thread.currentThread().getName() + ": " + i);
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
```

Here the printNumbers() method is not marked as synchronized.

We create an object called **lockObject**. We then create a synchronized block of code using **synchronized(lockObject){}**

The advantage in using this approach, is that we can mark any custom block of code as synchronized. ( It can be an entire method, or it can be even a single line in the entire method. )


The worker code is shown below:

```java
class RunnableWorkerExample3 implements Runnable {
    PrintUtilExample3 pu3;
    public  RunnableWorkerExample3(PrintUtilExample3 pu3){
        this.pu3 = pu3;
    }
    @Override
    public void run() {
        pu3.printNumbers();
    }
}
```

The main class is shown below:

```java
public class SynchronizedCustomObjectDemo {
    public static void main(String[] args) {
        PrintUtilExample3 pu3 = new PrintUtilExample3();
        Runnable r = new RunnableWorkerExample3(pu3);
        Thread t1 = new Thread(r);
        Thread t2 = new Thread(r);
        Thread t3 = new Thread(r);

        t1.start();
        t2.start();
        t3.start();
    }
}
```

The output of the above program is shown below:

```bash
Thread-0: 0
Thread-0: 1
Thread-0: 2
Thread-0: 3
Thread-0: 4
Thread-0: 5
Thread-2: 0
Thread-2: 1
Thread-2: 2
Thread-2: 3
Thread-2: 4
Thread-2: 5
Thread-1: 0
Thread-1: 1
Thread-1: 2
Thread-1: 3
Thread-1: 4
Thread-1: 5
```

In this approach as well we see that each thread completes printing from 0 to 5 before the next thread starts printing the numbers.

### How does this work

In this case the custom object created **lockObject** holds the lock. Rest of the locking mechanism is same as mentioned in the previous sections.

Also in the previous sections the entire method was marked as synchronized. But in this approach any block of code can be marked as synchronized which gives a greater flexibility.


# Code

All the code discussed in this article can be found in this [GitHub repo](https://github.com/aditya-sridhar/java-threads-synchronized-example).

# Issues with Synchronized

Synchronized does come with some issues. There maybe scenarios where we want a block of code to be synchronized only for write operations. But for read operations any number of concurrent threads should be allowed. In order to handle these scenarios there are other better approaches in Java which I will cover in a future articles.

# Congrats 😊
You now know what is synchronized and how to use it in Java.


### Feel free to connect with me in [LinkedIn] (https://www.linkedin.com/in/aditya1811/) or follow me in [twitter](https://twitter.com/adityasridhar18).

### If you liked this post, you can checkout my website [https://adityasridhar.com](https://adityasridhar.com) for other similar posts