Understanding Class Locks and Object Locks in Java with Example Code
This article explains the difference between class locks (static synchronized) and object locks (instance synchronized) in Java, demonstrates their behavior with multithreaded examples, and shows how lock scope affects execution order and synchronization.
In Java, adding synchronized to a static method creates a class lock (locking the Class object), while adding it to a non‑static method creates an object lock (locking the instance). The article demonstrates the distinction with concrete code examples.
Example 1: Three methods in Task2 – doLongTimeTaskA and doLongTimeTaskB are static synchronized (class lock), and doLongTimeTaskC is instance synchronized (object lock). Three threads (ThreadA, ThreadB, ThreadC) invoke these methods concurrently.
public class Task2 {
public synchronized static void doLongTimeTaskA() { /* ... */ }
public synchronized static void doLongTimeTaskB() { /* ... */ }
public synchronized void doLongTimeTaskC() { /* ... */ }
} class ThreadA extends Thread {
private Task2 mTask2;
public ThreadA(Task2 tk) { mTask2 = tk; }
public void run() { mTask2.doLongTimeTaskA(); }
}
// ThreadB and ThreadC are similar, calling B and C respectively Task2 mTask2 = new Task2();
ThreadA ta = new ThreadA(mTask2);
ThreadB tb = new ThreadB(mTask2);
ThreadC tc = new ThreadC(mTask2);
ta.setName("A"); tb.setName("B"); tc.setName("C");
ta.start(); tb.start(); tc.start();The output shows that A and B (both class‑locked) run sequentially, while C (object‑locked) runs independently, confirming that class locks and object locks are different.
Example 2: To make object locks synchronize, the same Task2 instance must be shared. Two separate instances ( mTaska and mTaskb ) are passed to ThreadA and ThreadB, each calling the object‑locked method doLongTimeTaskC . The result shows asynchronous execution because the locks protect different objects.
Task2 mTaska = new Task2();
Task2 mTaskb = new Task2();
ThreadA ta = new ThreadA(mTaska);
ThreadB tb = new ThreadB(mTaskb);
ta.setName("A"); tb.setName("B");
ta.start(); tb.start();Finally, when both threads use the same class lock (by calling the static synchronized method doLongTimeTaskA ) without changing the main method, the output shows that Thread B starts only after Thread A finishes, demonstrating that a class lock is effective across all instances of the class.
class ThreadA extends Thread { /* run calls mTask2.doLongTimeTaskA(); */ }
class ThreadB extends Thread { /* run calls mTask2.doLongTimeTaskA(); */ }
// main creates a single Task2 instance and starts both threadsIn summary, class locks synchronize across all instances of a class, while object locks synchronize only on the specific instance they protect.
Selected Java Interview Questions
A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.