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
// ...
}
}