- The difference between synchronized method and synchronized block is selection of lock on which critical section is locked. Synchronized method depending upon whether its a static method or non static locks on either class level lock or object lock.
- Class level lock is one for each class and represented by class literal e.g. String.class. Object level lock is provided by current object e.g. this instance, You should never mix static and non static synchronized method in Java
- On the other hand synchronized block locks on monitor evaluated by expression provided as parameter to synchronized block.
- One significant difference between synchronized method and block is that, Synchronized block generally reduce scope of lock. As scope of lock is inversely proportional to performance, its always better to lock only critical section of code. One of the best example of using synchronized block is double checked locking in Singleton pattern where instead of locking whole getInstance() method we only lock critical section of code which is used to create Singleton instance.
- Synchronized block provide granular control over lock(“very detailed control”, meaning you can control a lot of specific aspects), as you can use arbitrary any lock to provide mutual exclusion to critical section code. On the other hand synchronized method always lock either on current object represented by this keyword or class level lock, if its static synchronized method.
- Synchronized block can throw throw java.lang.NullPointerException if expression provided to block as parameter evaluates to null, which is not the case with synchronized methods.
- In case of synchronized method, lock is acquired by thread when it enter method and released when it leaves method, either normally or by throwing Exception. On the other hand in case of synchronized block, thread acquires lock when they enter synchronized block and release when they leave synchronized block.
public class SycnronizationExample { public synchronized void lockedByThis() { System.out.println(" This synchronized method is locked by current" instance of object i.e. this"); } public static synchronized void lockedByClassLock() { System.out.println("This static synchronized method is locked by class level lock of this class i.e. SychronizationExample.class"); } public void lockedBySynchronizedBlock() { System.err.println("This line is executed without locking"); Object obj = String.class; //class level lock of Stirng class synchronized(obj) { System.out.println("synchronized block, locked by lock represented using obj variable"); } } }