Java synchronized keyword

Java synchronized keyword marks a block or method a critical section. A critical section is where one and only one thread is executing at a time, and the thread holds the lock for the synchronized section.

synchronized keyword helps in writing concurrent parts of the applications, to protect shared resources within this block.

The synchronized keyword can be use with –

  • a code block
  • a method

1. Java synchronized block

1.1. Syntax

The general syntax for writing a synchronized block is as follows. Here lockObject is a reference to an object whose lock associates with the monitor that the synchronized statements represent.

synchronized( lockObject ) 
{
   // synchronized statements
}

1.2. Internal working

When a thread wants to execute synchronized statements inside the synchronized block, it MUST acquire the lock on lockObject‘s monitor. At a time, only one thread can acquire the monitor of a lock object. So all other threads must wait till this thread, currently acquired the lock, finish it’s execution.

In this way, synchronized keyword guarantees that only one thread will be executing the synchronized block statements at a time, and thus prevent multiple threads from corrupting the shared data inside the block.

Keep in mind that if a thread is put on sleep (using sleep() method) then it does not release the lock. At this sleeping time, no thread will be executing the synchronized block statements.

Java synchronization will throw NullPointerException if lock object used in 'synchronized (lock)' is null.

1.3. Java synchronized block example

Java program to demonstrate the usage of synchronized block. In given example, we have a MathClass with a method printNumbers(). This method will print the numbers starting from 1 to the argument number N.

Notice that the code in printNumbers() method is inside synchronized block.

public class MathClass 
{
    void printNumbers(int n) throws InterruptedException 
    {
        synchronized (this) 
        {
            for (int i = 1; i <= n; i++) 
            {
                System.out.println(Thread.currentThread().getName() + " :: "+  i);
                Thread.sleep(500);
            }
        }
    }
}

I have created two threads which start executing the printNumbers() method exactly at same time. Due to block being synchronized, only one thread is allowed access and other thread has to wait until first thread is finished.

public class Main 
{
    public static void main(String args[]) 
    {
        final MathClass mathClass = new MathClass();

        //first thread
        Runnable r = new Runnable() 
        {
            public void run() 
            {
                try {
                    mathClass.printNumbers(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
      
        new Thread(r, "ONE").start();
        new Thread(r, "TWO").start();
    }
}

Program output.

ONE :: 1
ONE :: 2
ONE :: 3

TWO :: 1
TWO :: 2
TWO :: 3

2. Java synchronized method

2.1. Syntax

The general syntax for writing a synchronized method is as follows. Here lockObject is a reference to an object whose lock associates with the monitor that the synchronized statements represent.

<access modifier> synchronized method( parameters ) 
{
    // synchronized code
}

2.2. Internal working

Similar to synchronized block, a thread MUST acquire the lock on the associated monitor object with synchronized method. In case of synchronized method, the lock object is –

  • ‘.class’ object – if the method is static.
  • ‘this’ object – if the method is not static. ‘this’ refer to reference to current object in which synchronized method is invoked.

Read More : Object level lock vs Class level lock in Java

Java synchronized keyword is re-entrant in nature it means if a synchronized method calls another synchronized method which requires same lock then current thread which is holding lock can enter into that method without acquiring lock.

2.3. Java synchronized method example

Similar to synchronized block example, we can apply synchronized keyword at printNumber() method and it will make the method as synchronized. Now if we again run the example, we will get the similar output.

public class MathClass 
{
    synchronized void printNumbers(int n) throws InterruptedException 
    {
        for (int i = 1; i <= n; i++) 
        {
            System.out.println(Thread.currentThread().getName() + " :: "+  i);
            Thread.sleep(500);
        }
    }
}

Program output.

ONE :: 1
ONE :: 2
ONE :: 3

TWO :: 1
TWO :: 2
TWO :: 3

Drop me your questions in comments.

Happy Learning !!

Was this post helpful?

Join 7000+ Fellow Programmers

Subscribe to get new post notifications, industry updates, best practices, and much more. Directly into your inbox, for free.

6 thoughts on “Java synchronized keyword”

  1. Dear Sir,

    In Section 2.2 you have written,

    In case of synchronized method, the lock object is –
    ‘.class’ object – if the method is static.
    ‘this’ object – if the method is not static. ‘this’ refer to reference to current object in which synchronized method is invoked.
    but In case of synchronized block the same thing does happen.

    case 1: ‘.class’ object – if the method is static.
    static void printNumbers(int n) throws InterruptedException
    {
    synchronized (MathClass.class)
    {
    for (int i = 1; i <= n; i++)
    {
    System.out.println(Thread.currentThread().getName() + " :: "+ i);
    Thread.sleep(500);
    }
    }
    }

    case 2: this’ object – if the method is not static.

    void printNumbers(int n) throws InterruptedException
    {
    synchronized ( this)
    {
    for (int i = 1; i <= n; i++)
    {
    System.out.println(Thread.currentThread().getName() + " :: "+ i);
    Thread.sleep(500);
    }
    }
    }

    Please let me know if I am wrong.

    Thanks & Regards
    Tarun

    Reply
    • Hi Tarun,

      we are starting 2 threads on same objects, so in non static method lock is applied in Object so only one thread can execute the critical section code.
      on applying synchronized on static method or synchronized ( classname.class), here lock is applied on class level so If we are starting 2 threads on 2 different objects the class then also only one thread can execute the critical section code.

      Thanks,
      Anil

      Reply
      • Hi Anil,

        there is one thing from my side that if we starting 2 threads on 2 different objects then both the Threads are process simultaneously as for each object there is its own critical section of code.

        For Example::

        class PrintNumbers {
        synchronized void printingNumbers(int number) throws InterruptedException {
        for (int j = 0; j {
        try {
        printNumbers1.printingNumbers(10);
        } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        }
        }, “Thread1”).start();

        new Thread(() -> {
        try {
        printNumbers2.printingNumbers(100);
        } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        }
        }, “Thread2”).start();

        }

        }

        Output ::

        Thread[Thread1,5,main] :: 10
        Thread[Thread2,5,main] :: 100
        Thread[Thread1,5,main] :: 20
        Thread[Thread2,5,main] :: 200
        Thread[Thread2,5,main] :: 300
        Thread[Thread1,5,main] :: 30
        Thread[Thread2,5,main] :: 400
        Thread[Thread1,5,main] :: 40
        Thread[Thread2,5,main] :: 500
        Thread[Thread1,5,main] :: 50

        please correct me if i am wrong anywhere in it.

        Thanks and Best Regards,
        Naveen Jain.

        Reply
  2. Hi I ran the same code using synchronized block.It is giving alternate output from threads..

    O/P when n=2

    ONE::0
    TWO::0
    ONE::1
    TWO::1

    Code:

    public class SynchronizedExample {

    public void printNumbers(int n) throws InterruptedException {

    synchronized (this) {

    for(int i=0;i<n;i++) {
    System.out.println(Thread.currentThread().getName()+ "::"+i);
    Thread.sleep(500);
    }
    }

    }

    public static void main(String[] args) {
    // TODO Auto-generated method stub

    Runnable r=new Runnable() {

    @Override
    public void run() {
    SynchronizedExample ex=new SynchronizedExample();
    try {
    ex.printNumbers(2);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    }
    };

    new Thread(r,"ONE").start();
    new Thread(r,"TWO").start();

    }

    }

    Reply
    • Hi Dipanshu,

      You have created the SynchronizedExample object inside the run method only and that is different then creating it outside as given in the example.

      In your scenario both the threads are having a different lock objects thats why synchronized keyword wont help in your scenario.

      If you create the SynchronizedExample object outside the run method then in that case associated monitor object is same for both the threads and you get the output mentioned in the above example.

      Reply

Leave a Comment

HowToDoInJava

A blog about Java and its related technologies, the best practices, algorithms, interview questions, scripting languages, and Python.