Class Level Lock in Java

Last Updated : 17 Mar, 2026

Class level lock is a lock on the Class object, used when working with static synchronized methods or blocks. Only one thread can execute any static synchronized code of a class at a time, regardless of number of objects.
It is mainly used to protect shared static data.

  • Lock is applied on the class, not on objects (common for all instances).
  • Achieved using static synchronized methods or synchronized(ClassName.class) block.
  • Ensures only one thread executes static synchronized code at a time.

Methods of Class Level Lock

1. Using the synchronized static method

This method automatically acquires the class-level lock when a thread enters it. Only one thread can execute any static synchronized method of the class at a time.

  • Lock is on ClassName.class
  • Applied directly using static synchronized
  • Simple and automatic locking
Java
class Geek implements Runnable {

    // Method 1
    // @Override
    public void run() { Lock(); }

    // Method 2
    // Method is static
    public static synchronized void Lock()
    {
        // Gwetting the name of current thread by using
        // getName() method to get name of the thread and
        // currentThread() to get the current thread
        System.out.println(
            Thread.currentThread().getName());

        // class level lock
        synchronized (Geek.class)
        {
            System.out.println(
                "in block "
                + Thread.currentThread().getName());
            System.out.println(
                "in block "
                + Thread.currentThread().getName()
                + " end");
        }
    }

    // Method 3
    // Main driver method
    public static void main(String[] args)
    {
        // Creating an object of above class
        // in the main() method
        Geek g1 = new Geek();

        // Sharing the same object across two Threads

        // Creating an object of thread class where
        // t1 takes g1
        Thread t1 = new Thread(g1);

        // Creating an object of thread class where
        // t2 takes g1
        Thread t2 = new Thread(g1);

        // Creating second object of above class
        // in the main() method
        Geek g2 = new Geek();

        // Creating an object of thread class where
        // t3 takes g2
        Thread t3 = new Thread(g2);

        // setName() method is used to set name to the
        // thread
        t1.setName("t1");
        t2.setName("t2");
        t3.setName("t3");

        // start() method is used for initiating the current
        // thread
        t1.start();
        t2.start();
        t3.start();
    }
}

Output
t1
in block t1
in block t1 end
t3
in block t3
in block t3 end
t2
in block t2
in block t2 end

2. Using synchronized block method 

This method uses a block where the class object is explicitly locked using ClassName.class. It allows better control by synchronizing only specific code. 

  • Lock is on ClassName.class
  • Uses synchronized(ClassName.class)
  • More flexible than method-level synchronization.
Java
class Geek implements Runnable {

    // Method 1
    // @Override
    public void run()
    {
        // Acquire lock on .class reference
        synchronized (Geek.class)

        // ClassName is name of the class containing method.
        {
            {
                System.out.println(
                    Thread.currentThread().getName());

                System.out.println(
                    "in block "
                    + Thread.currentThread().getName());
                System.out.println(
                    "in block "
                    + Thread.currentThread().getName()
                    + " end");
            }
        }

        // Method 2
        // Main driver method
        public static void main(String[] args)
        {
            // Creating an object of above class
            // in the main() method
            Geek g1 = new Geek();

            // Creating an object of thread class i.e Thread
            // 1 where t1 takes g1 object
            Thread t1 = new Thread(g1);
            // Here, creating Thread 2 where t2 takes g1
            // object
            Thread t2 = new Thread(g1); 

            // Creating another object of above class
            // in the main() method
            Geek g2 = new Geek();
          
            // Now Creating Thread 3 where t3 takes g2 object
            Thread t3 = new Thread(g2);

            // Ginving custom names to above 3 threads
            // using the setName() method
            t1.setName("t1");
            t2.setName("t2");
            t3.setName("t3");

            // start() method is used to begin execution of
            // threads
            t1.start();
            t2.start();
            t3.start();
        }
    }

Output:

t1
in block t1
in block t1 end
t3
in block t3
in block t3 end
t2
in block t2
in block t2 end

Output explanation: Thread t1 acquired the class lock by entering the synchronized block. Other threads waited until t1 released the lock
 

Comment