Static Synchronization in Java: Locking at the Class Level

Learn about static synchronization in Java, where making a static method synchronized locks the class itself rather than the object. Discover how this approach impacts concurrency and thread safety in Java applications.



Static Synchronization in Java

If you make any static method synchronized, the lock will be on the class, not on the object.

Static Synchronization

Static synchronization is used to prevent thread interference and consistency problems in scenarios where multiple threads access static methods of a class.

Problem without Static Synchronization

Suppose there are two objects of a shared class (e.g., Table) named object1 and object2. In the case of synchronized methods and synchronized blocks, there cannot be interference between threads t1 and t2 or t3 and t4 because t1 and t2 both refer to a common object that has a single lock. However, there can be interference between t1 and t3 or t2 and t4 because t1 acquires one lock and t3 acquires another lock. Static synchronization solves this problem by locking the class itself, preventing interference between any threads accessing static methods.

Example of Static Synchronization

In this example, we use the synchronized keyword on the static method to perform static synchronization.

FileName: TestSynchronization4.java

class Table {     
synchronized static void printTable(int n) {    
    for(int i = 1; i <= 10; i++) {    
    System.out.println(n * i);    
    try {    
        Thread.sleep(400);    
    } catch(Exception e) {}    
    }    
}    
}    
    
class MyThread1 extends Thread {    
public void run() {    
    Table.printTable(1);    
}    
}    
class MyThread2 extends Thread {    
public void run() {    
    Table.printTable(10);    
}    
}    
class MyThread3 extends Thread {    
public void run() {    
    Table.printTable(100);    
}    
}    
class MyThread4 extends Thread {    
public void run() {    
    Table.printTable(1000);    
}    
}    
    
public class TestSynchronization4 {    
public static void main(String t[]) {    
    MyThread1 t1 = new MyThread1();    
    MyThread2 t2 = new MyThread2();    
    MyThread3 t3 = new MyThread3();    
    MyThread4 t4 = new MyThread4();    
    t1.start();    
    t2.start();    
    t3.start();    
    t4.start();    
}    
}  
    
Output

1
2
3
4
5
6
7
8
9
10
10       
20
30
40
50
60
70
80
90
100
100
200
300
400
500
600
700
800
900
1000
1000
2000
3000
4000
5000
6000
7000
8000
9000
10000
    

Example of Static Synchronization Using Anonymous Class

In this example, we use anonymous classes to create the threads.

FileName: TestSynchronization5.java

class Table {  
synchronized static void printTable(int n) {  
    for(int i = 1; i <= 10; i++) {  
    System.out.println(n * i);  
    try {  
        Thread.sleep(400);  
    } catch(Exception e) {}  
    }  
}  
}  

public class TestSynchronization5 {  
public static void main(String[] args) {  
    Thread t1 = new Thread() {  
    public void run() {  
        Table.printTable(1);  
    }  
    };  
    
    Thread t2 = new Thread() {  
    public void run() {  
        Table.printTable(10);  
    }  
    };  
    
    Thread t3 = new Thread() {  
    public void run() {  
        Table.printTable(100);  
    }  
    };  
    
    Thread t4 = new Thread() {  
    public void run() {  
        Table.printTable(1000);  
    }  
    };  
    t1.start();  
    t2.start();  
    t3.start();  
    t4.start();  
}  
}  
    
Output

1
2
3
4
5
6
7
8
9
10
10       
20
30
40
50
60
70
80
90
100
100
200
300
400
500
600
700
800
900
1000
1000
2000
3000
4000
5000
6000
7000
8000
9000
10000
    

Synchronized Block on a Class Lock

The block synchronizes on the lock of the object denoted by the reference .class name .class. A static synchronized method printTable(int n) in class Table is equivalent to the following declaration:


static void printTable(int n) {  
synchronized (Table.class) { // Synchronized block on class A  
    // ...  
}  
}