Static Vs Non-static synchronization in Java

Synchronization is used to control the access to shared resources in a multithreaded environment, ensuring that only one thread can access the shared resource at a time. There are two types of synchronization: static synchronization and non-static synchronization.

Static Synchronization in Java

Static synchronization is applied to static methods or blocks. When a method or block is declared as static and synchronized, it means the lock is acquired on the class object itself (represented by Class.class). Only one thread can acquire the lock on the class object, preventing other threads from entering the synchronized static method or block until the lock is released.

public class MyClass { public static synchronized void staticSyncMethod() { // Code to be executed in a synchronized manner } }

Static synchronized block

public class MyClass { public static void someMethod() { synchronized(MyClass.class) { // Code to be executed in a synchronized manner } } }
  1. The lock is acquired on the class object (Class.class).
  2. Only one thread can execute a static synchronized method or access a static synchronized block at a time.
  3. Multiple threads can execute non-synchronized static methods concurrently with static synchronized methods.

Examples | When you might use static synchronization:

  1. A class that has a counter that keeps track of the number of times a method has been called. You would want to use static synchronization to protect this counter so that multiple threads don't try to increment it at the same time.
  2. A class that has a shared resource, such as a database connection. You would want to use static synchronization to protect this resource so that multiple threads don't try to use it at the same time.

Non-static Synchronization

Non-static synchronization is applied to instance methods or blocks. When a method or block is declared as synchronized (without the static keyword), it means the lock is acquired on the instance (object) itself. Each instance of a class has its own lock, and different instances can be accessed concurrently by multiple threads.

public class MyClass { public synchronized void nonStaticSyncMethod() { // Code to be executed in a synchronized manner } }

Non-static synchronized block

public class MyClass { public void someMethod() { synchronized(this) { // Code to be executed in a synchronized manner } } }
  1. The lock is acquired on the instance (object) of the class.
  2. Each instance has its own lock, allowing multiple threads to execute synchronized methods on different instances simultaneously.
  3. Non-synchronized instance methods can be executed concurrently by multiple threads.

Examples | When you might use non-static synchronization:

  1. A class that has a method that updates a private field. You would want to use non-static synchronization to protect this field so that only the thread that owns the instance can update it.
  2. A class that has a method that locks a mutex. You would want to use non-static synchronization to protect this mutex so that only one thread can lock it at a time.

Conclusion

Static synchronization and non-static synchronization are independent of each other. Acquiring a lock on a static method or block doesn't block the execution of non-static synchronized methods, and vice versa.