Synchronized keyword - example of usage

SynchronizedExample.java
public class SynchronizedExample {
    // Synchronized method on the instance (this)
    public synchronized void syncMethodOnInstance() {
        // Code that is synchronized on the current instance
        System.out.println("Synchronized on the instance (this)");
    }
 
    // Synchronized block on the instance (this)
    public void syncBlockOnInstance() {
        synchronized (this) {
            // Code that is synchronized on the current instance
            System.out.println("Synchronized block on the instance (this)");
        }
    }
 
    // Synchronized method on the class (Class object)
    public static synchronized void syncMethodOnClass() {
        // Code that is synchronized on the Class object
        System.out.println("Synchronized on the class (Class object)");
    }
 
    // Synchronized block on the class (Class object)
    public static void syncBlockOnClass() {
        synchronized (SynchronizedExample.class) {
            // Code that is synchronized on the Class object
            System.out.println("Synchronized block on the class (Class object)");
        }
    }
 
    // Main method to run the examples
    public static void main(String[] args) {
        SynchronizedExample example = new SynchronizedExample();
 
        // Calling instance methods
        example.syncMethodOnInstance();
        example.syncBlockOnInstance();
 
        // Calling static methods
        syncMethodOnClass();
        syncBlockOnClass();
    }
}

In the provided Java example, we have different ways of applying synchronization:

Synchronized Method on Instance (this):

The syncMethodOnInstance method is synchronized on the instance of the class (this). This means that only one thread can execute this method on the same instance of SynchronizedExample at any given time.

Synchronized Block on Instance (this):

In the syncBlockOnInstance method, a specific block of code is synchronized on the current instance (this). This allows for more granular control, as only the code within the synchronized block is subject to mutual exclusion, as opposed to the entire method.

Synchronized Method on Class (Class object):

The syncMethodOnClass method is a static method synchronized on the Class object of SynchronizedExample. This means that only one thread can execute this method across all instances of the class at a time. It's useful for controlling access to static or class-level data.

Synchronized Block on Class (Class object):

The syncBlockOnClass method contains a synchronized block on the Class object of SynchronizedExample. This synchronized block restricts execution to one thread across all instances for that specific block of code, useful for handling static data shared across instances.

These synchronization methods in Java are crucial for thread safety when multiple threads access and modify shared resources. Using synchronized on instance methods or blocks (this) is suitable for instance-specific resource management, while using synchronized on static methods or blocks (Class object) is appropriate for class-level resource management, such as static variables.