synchronized block vs synchronized method in Java

1. Introduction

In Java, synchronization is a mechanism that is used to control access to shared resources by multiple threads, preventing concurrent execution that may lead to inconsistent state or data corruption.

Synchronization can be achieved by using synchronized methods or synchronized blocks within methods. A synchronized method locks the entire method, while a synchronized block only locks the specified object or class, allowing for more granular control over the blocks of code that need synchronization.

2. Key Points

1. synchronized methods lock the entire method and prevent any other thread from invoking any synchronized method on the same object.

2. synchronized blocks lock only the object specified in their parameter, allowing other threads to access the remaining synchronized methods.

3. synchronized methods can lock either on the instance (object) or the class (for static methods), whereas synchronized blocks can specify the lock object.

4. synchronized blocks offer better performance as they minimize the scope of synchronization.

3. Differences

Synchronized Method Synchronized Block
Locks the entire method. Locks only the specified object or class within the block.
There is no need to specify the lock object; non-static methods lock on this, and static methods lock on the class object. Requires an explicit object or class to lock on.
Suitable when the entire method must be executed only one thread at a time. Useful when you need to perform only a part of a method synchronously, reducing contention and improving performance.
When a method is synchronized, it prevents multiple threads from executing any synchronized method on the same object simultaneously. It allows multiple threads to access non-synchronized code blocks of the same object concurrently, leading to better resource utilization.

4. Example

class Counter {
    private int count = 0;

    // Synchronized Method
    public synchronized void incrementSyncMethod() {
        count++;
        // Other code
    }

    // Method containing Synchronized Block
    public void incrementSyncBlock() {
        // Some non-synchronized work can happen here

        // Critical section is synchronized
        synchronized(this) {
            count++;
            // Other critical code
        }

        // Some more non-synchronized work can happen here
    }

    public int getCount() {
        return count;
    }
}

public class Main {
    public static void main(String[] args) {
        Counter counter = new Counter();

        // Using Synchronized Method
        counter.incrementSyncMethod();

        // Using Synchronized Block
        counter.incrementSyncBlock();

        System.out.println("Count: " + counter.getCount());
    }
}

Output:

Count: 2

Explanation:

1. incrementSyncMethod is a synchronized method. When a thread enters this method, it acquires a lock on the entire method.

2. incrementSyncBlock contains a synchronized block. When a thread enters this synchronized block, it acquires a lock only on the specified object (this in this case), not on the entire method.

3. Both methods are used to increment the count variable safely in a multi-threaded environment.

4. The main method invokes both synchronized methods, showing they can be used to perform thread-safe increments on the count.

5. When to use?

- Use synchronized methods when you need to synchronize the entire method and you don't have any performance concerns or when you're working with simple synchronization needs.

- Use synchronized blocks when you have critical sections within your methods that need synchronization. This can help improve the application's performance by reducing the scope of synchronization.

Comments