Both Object level lock and Class level lock are used to achieve synchronization mechanisms in a multi-threaded application.
Object level lock
Every object in Java has a unique lock. If a thread wants to execute a synchronized method on a given object, first it has to get a lock of that object. Once thread got the lock then it is allowed to execute any synchronized method on that object. Once method execution completes automatically thread releases the lock. Acquiring and release lock internally is taken care of by the JVM. Object level lock is a mechanism when we want to synchronize a non-static method or non-static code block such that only one thread will be able to execute the code block on a given instance of the class. This can always be done to make instance-level data thread-safe.
Example
public class ObjectLevelLockTest implements Runnable { @Override public void run() { objectLock(); } public void objectLock() { System.out.println(Thread.currentThread().getName()); synchronized(this) { System.out.println("Synchronized block " + Thread.currentThread().getName()); System.out.println("Synchronized block " + Thread.currentThread().getName() + " end"); } } public static void main(String[] args) { ObjectLevelLockTest test1 = new ObjectLevelLockTest(); Thread t1 = new Thread(test1); Thread t2 = new Thread(test1); ObjectLevelLockTest test2 = new ObjectLevelLockTest(); Thread t3 = new Thread(test2); t1.setName("t1"); t2.setName("t2"); t3.setName("t3"); t1.start(); t2.start(); t3.start(); } }
Output
t1 t2 t3 Synchronized block t1 Synchronized block t3 Synchronized block t1 end Synchronized block t3 end Synchronized block t2 Synchronized block t2 end
Class level lock
Every class in Java has a unique lock which is nothing but a class level lock. If a thread wants to execute a static synchronized method, then thread requires a class level lock. Once a thread got the class level lock, then it is allowed to execute any static synchronized method of that class. Once method execution completes automatically thread releases the lock. The Class level lock prevents multiple threads to enter in a synchronized block in any of all available instances on runtime.
Example
public class ClassLevelLockTest implements Runnable { @Override public void run() { classLock(); } public void classLock() { System.out.println(Thread.currentThread().getName()); synchronized(ClassLevelLockTest.class) { System.out.println("Synchronized block " + Thread.currentThread().getName()); System.out.println("Synchronized block " + Thread.currentThread().getName() + " end"); } } public static void main(String[] args) { ClassLevelLockTest test1 = new ClassLevelLockTest(); Thread t1 = new Thread(test1); Thread t2 = new Thread(test1); ClassLevelLockTest test2 = new ClassLevelLockTest(); Thread t3 = new Thread(test2); t1.setName("t1"); t2.setName("t2"); t3.setName("t3"); t1.start(); t2.start(); t3.start(); } }
Output
t3 t2 t1 Synchronized block t3 Synchronized block t3 end Synchronized block t2 Synchronized block t2 end Synchronized block t1 Synchronized block t1 end