Object vs Class Level Locks for Thread Synchronization in Java : Free Java Tutorials

There exist two types of locks in Java to carry out thread synchronization. They are object level lock and class level lock. These two locks are always there for each class as well as each object in java to support thread synchronization.

Object level vs Class level locks in thread synchronization

In thread synchronization, there are two types of locks on threads in java:

Object level lock:

Every object in Java has one unique object level lock. Whenever a thread wants to execute any synchronized method, it has to possess object level lock of that object on which thread wants to execute the synchronized method.

In short, whenever we use the synchronized keyword, the concept of object level lock will be there.

If multiple threads are operating on same java object then synchronization is a must.

If multiple threads are operating on different java objects then synchronization is not required.

Class level lock:

Every class in Java has one unique class level lock. Whenever a thread wants to execute any static synchronized method, it has to possess the class level lock of that under which the static synchronized method is defined.

Once thread got the class level lock, then it is allowed to execute any static synchronized method of that class. After the completion of that method, automatically thread releases class level lock.

While a thread executes static synchronized method, the remaining threads are not allowed to execute any other static synchronized methods of the same class simultaneously.

But other threads can execute any of the following methods simultaneously.

  1. Synchronized instance methods (this method will require object level lock and hence it is independent of class level lock)
  2. Normal static methods
  3. Normal instance methods

 

Let’s understand this with an example.

class MyThread1 extends Thread 
{		
	public void run()
	{
		Trial.trial1("Name-1");
		System.out.println("MyThread-1 has finished execution");
	}
}

class MyThread2 extends Thread 
{		
	public void run()
	{
		Trial.trial2("Name-2");
		System.out.println("MyThread-2 has finished execution");
	}
}

class MyThread3 extends Thread 
{	
	Trial obj;
	MyThread3(Trial obj)
	{
		this.obj = obj;
	}
	
	public void run()
	{
		obj.trial3("Name-3");
		System.out.println("MyThread-3 has finished execution");
	}
}

class MyThread4 extends Thread 
{	
	public void run()
	{
		Trial.trial4("Name-4");
		System.out.println("MyThread-4 has finished execution");
	}
}

class MyThread5 extends Thread 
{	
	Trial obj;
	MyThread5(Trial obj)
	{
		this.obj = obj;
	}
	
	public void run()
	{
		obj.trial5("Name-5");
		System.out.println("MyThread-5 has finished execution");
	}
}

class Trial 
{	
	public static synchronized void trial1(String name)
	{
		try
		{
			System.out.println("Trial-1 is sleeping for 5 seconds");
			Thread.sleep(5000);
		}
		catch(InterruptedException exp)
		{
			System.out.println("Trial-1 has been interrupted");
		}	
		System.out.println("Trial-1 wants to print " + name);
	}
	
	public static synchronized void trial2(String name)
	{
		System.out.println("Trial-2 wants to print " + name);
	}
	
	public synchronized void trial3(String name)
	{
		System.out.println("Trial-3 wants to print " + name);
	}
	
	public static void trial4(String name)
	{
		System.out.println("Trial-4 wants to print " + name);
	}
	
	public void trial5(String name)
	{
		System.out.println("Trial-5 wants to print " + name);
	}
}

// Main class
public class Demo
{
	public static void main(String args[])
	{
		Trial obj = new Trial();
		
		MyThread1 thread1 = new MyThread1();
		MyThread2 thread2 = new MyThread2();
		MyThread3 thread3 = new MyThread3(obj);
		MyThread4 thread4 = new MyThread4();
		MyThread5 thread5 = new MyThread5(obj);
		
		thread1.start();
		try 
		{
			Thread.sleep(1000);	
		}
		catch(InterruptedException exp)
		{
			System.out.println("Main thread has been interrupted");
		}
		thread2.start();
		thread3.start();
		thread4.start();
		thread5.start();		
	}
}

Output:

Trial-1 is sleeping for 5 seconds
Trial-3 wants to print Name-3
MyThread-3 has finished execution
Trial-5 wants to print Name-5
Trial-4 wants to print Name-4
MyThread-5 has finished execution
MyThread-4 has finished execution
Trial-1 wants to print Name-1
MyThread-1 has finished execution
Trial-2 wants to print Name-2
MyThread-2 has finished execution

Let’s understand the above output.

We have deliberately made main thread to sleep for 1 second so that we can ensure that MyThread1 will start its execution first.

MyThread1 starts its execution and it gets the class level lock since it executes static synchronized method trial1(). Mythread1 sleeps for 5 seconds during its lifecycle. In this 5 seconds, all the other threads will finish its execution.

But MyThread2 cannot execute static synchronized method trial2() since it does not have the class level lock for the class named Trial.

MyThread2 will execute only after 5 seconds and we can see this delay in the execution of MyThread2 when we run the program.

 

This is all about Object vs Class level locks in Java for thread synchronization. Hope you find this tutorial helpful.

Leave a Comment

Your email address will not be published. Required fields are marked *