Static Synchronization In Java

While the synchronized method restricts access to only one thread at a time, it does not promise the output order if the method's operations are not in sequence or if the method does not explicitly manage the execution order.

Hence, to ensure synchronization of behavior, utilizing an instance-level lock is insufficient. Instead, a class-level lock is required, which can be implemented through static synchronization.

In essence, when you designate a static method as synchronized, the synchronization will be at the class level rather than the object level. This means that only one thread can execute operations on that method due to the class-level lock. To illustrate this concept, let's examine the scenario below.

Consider a scenario where a class contains several static synchronized methods (such as demo1, demo2, demo3, demo4). If one thread is currently accessing the method demo1, it will prevent any other thread from accessing any other static synchronized methods simultaneously.

Syntax:

Example

static synchronized returnType methodName(Type parameters) { 

// code 

}

Why static synchronization?

Consider having two instances of a class called Table, denoted as object1 and object2. When utilizing synchronized methods or synchronized blocks, interference between object1 and object2, or any other pair like object3 and object4, is prevented. This is due to object1 and object2 pointing to the same object, which possesses a singular lock.

Interference may occur between t1 and t3 or t2 and t4 when t1 acquires a different lock than t3, or t2 acquires a different lock than t4. To prevent interference between these threads, static synchronization is implemented to address this issue.

Therefore, static synchronization is utilized to ensure that a shared resource is accessed in a manner that is safe for multiple threads.

Static Synchronization Example

Example

Example

class Print

{

// static synchronized method declaration

    public static synchronized void printMessage(String s)

    {

        for(int i = 0; i < 4; i++)

        {

            System.out.print("Good Night: ");

            System.out.println(s);

            try{

                Thread.sleep(1000);  //sleep thread for 1 sec

            }

            catch(InterruptedException e)

            {

            }

        }

    }

}

class MyThrd extends Thread {

    Print p;

    String s;

    MyThrd(Print p, String s)

    {

        this.p = p;

        this.s = s;

    }

    public void run()

    {

        p.printMessage(s);

    }

}

public class Main {

    public static void main(String arg[])

    {

        Print p1 = new Print();

        Print p2 = new Print();

        MyThrd th1 = new MyThrd(p1,"Mahi");

        MyThrd th2 = new MyThrd(p2,"Sachin");

        th1.start(); // start thread th1

        th2.start(); // start thread th2

    } 

}

Output:

Output

Good Night: Mahi

Good Night: Mahi

Good Night: Mahi

Good Night: Mahi

Good Night: Sachin

Good Night: Sachin

Good Night: Sachin

Good Night: Sachin



Good Night: Mahi

Good Night: Mahi

Good Night: Mahi

Good Night: Mahi

Good Night: Sachin

Good Night: Sachin

Good Night: Sachin

Good Night: Sachin

In the program provided, there are three classes: Print, MyThrd, and Main. Each of these classes is defined with its own set of properties and methods.

The Print class contains the necessary code for the child thread to execute.

The purpose of the MyThrd class is to inherit from the Thread class, set values to p (from the Print class) and s (from the String class), and call the printMessage function of the Print class.

The "Main" class serves as the primary class within the entire program, responsible for initiating a child thread.

Within the control flow of a program, the initial point of execution is the main method. Initially, two child threads are generated and linked to the print objects for those threads. Upon the activation of the th2.start instruction, the total count of threads will be three (main, th1, th2). The sequence of execution unfolds as detailed below.

Upon initiation, the child thread th1 commences its operation. Since the print method is synchronized as static, th1 obtains the class-level lock of the Print class and begins the execution of the printMessage method. Subsequently, any following thread, such as th2 in this scenario, must wait until the preceding thread has completed its execution to acquire the class-level lock.

Static Synchronization by Using the Anonymous Class

In this instance, a thread is being created using an unnamed class.

Example

Example

//Creating a class that contains a static synchronized method 

class Table{  

 synchronized static  void printTable(int n){  

   for(int i=1;i<=10;i++){  

     System.out.println(n*i);  

     try{  

       Thread.sleep(100);  

     }catch(Exception e){}  

   }  

 }  

}  

//Creating a Main class to call static synchronized method on threads run

public class Main {  

 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:

Output

100

200

300

400

500

600

700

800

900

1000

10

20

30

40

50

60

70

80

90

100

1000

2000

3000

4000

5000

6000

7000

8000

9000

10000

1

2

3

4

5

6

7

8

9

10

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:

Example

static void printTable(int n) {

    synchronized (Table.class) {       // Synchronized block on class A

        // ...

    }

}

Difference Between Synchronization and Static Synchronization

Aspect Synchronization Static Synchronization
Scope of Lock It locks the instance (object level). It locks the class object (class level)
Use It applies to instance methods or blocks. It applies to static methods or blocks.
Lock Context Lock is associated with the current object instance. The lock is related to the .class object of the class.
Thread Access It ensures that only one thread accesses the synchronized instance code of the same object at a time. It ensures only one thread accesses the synchronized static code of the entire class at a time.
Impact It affects thread safety at the instance level. It affects thread safety for shared static resources.
Uses To synchronize instance-specific data access. To synchronize shared data across all instances.
Declaration synchronized void instanceMethod() static synchronized void staticMethod()
Uses It is commonly used. It is not widely used.
Instances In synchronization, for each object, a new instance is created. In static synchronization, for the entire program, there is only one instance.

Important Points to Remember

  • It provides a lock at the class level, not for individual objects.
  • At a time, only one thread can execute the synchronized static method or block.
  • All instances of the class share the same lock.
  • Conclusion

In the preceding conversation, it was noted that a static synchronized method will acquire a lock on the class rather than the object. This occurs because the presence of the keyword static signifies that the lock is obtained on the class itself instead of an instance of the class.

The term "synchronized" indicates that the method can only be accessed by one thread at any given moment.

In the context of programming, "static synchronized" implies that exclusive access to the class is granted to a single thread at any given time.

Java Static Synchronization MCQs

  1. How can we achieve class-level lock?
  • Using Static Synchronization
  • Using Synchronization
  • Using Multithreading
  • Using

Explanation: When we declare a static method as synchronized, the lock will be on the class, not on the object. Since we can achieve the class-level lock, only one thread can do its operation on that method.

  1. Static synchronization can be applied to?
  • Only with static methods
  • Static methods and static block
  • With Multithreading
  • With Multithreading and static block

Explanation: Static synchronization can be applied to static methods and static blocks only.

  1. What are the valid static synchronization syntaxes?
  • static synchronized returnType methodName(Type parameters) { }
  • synchronized static returnType methodName(Type parameters) { }
  • public static synchronized returnType methodName(Type parameters) { }
  • public synchronized returnType methodName(Type parameters) { }
  • Only i
  • Only i and ii
  • Only ii and iii
  • Only i, ii, and iii

Explanation: We can declare a static synchronized method by using the i, ii, and iii statements.

  1. Which keyword is used to define a static synchronized method??
  • volatile
  • final
  • synchronized
  • transient

Explanation: Java provides the synchronization keyword to achieve synchronization.

  1. What does static synchronization ensure in Java?
  • Instance-level Synchronization
  • Class-level Synchronization
  • Object-level Synchronization
  • Thread-level Synchronization

In the context of synchronization, static synchronization guarantees synchronization at the level of the class.

Input Required

This code uses input(). Please provide values below: