Deadlock and Starvation in Java : Free Java Tutorials

Deadlock and Starvation are two very important concepts in Java. Starvation occurs when two or more threads get blocked and wait for each other for locks or resources. Deadlock is the extreme version of starvation where threads wait for an infinite amount of time and program execution reaches an impasse.

If two threads are waiting for each other forever (for infinite time), then such waiting causes deadlock.

Synchronized keyword is the only reason for deadlock situation. Hence, while using the synchronized keyword, we should take special care.

There are no resolution techniques for deadlock but several prevention techniques are available.

Example of Deadlock

class X
{	
	public synchronized void firstX(Y objy)
	{
		System.out.println("Main Thread has started execution of firstX() method");
		try
		{	
			Thread.sleep(2000);
		}
		catch(InterruptedException exp)
		{
			System.out.println("Main Thread has been interrupted");
		}
		System.out.println("Main Thread is trying to call secondY() method");
		objy.secondY();
	}
	
	public synchronized void secondX()
	{
		System.out.println("secondX() method has been called");
	}
}

class Y
{	
	public synchronized void firstY(X objx)
	{
		System.out.println("Child Thread has started execution of firstY() method");
		try
		{	
			Thread.sleep(2000);
		}
		catch(InterruptedException exp)
		{
			System.out.println("Child Thread has been interrupted");
		}
		System.out.println("Child Thread is trying to call secondX() method");
		objx.secondX();	
	}
	
	public synchronized void secondY()
	{
		System.out.println("secondY() method has been called");		
	}
}

public class Deadlock extends Thread 
{
	X objx = new X();
	Y objy = new Y();
	
	public void startThread()
	{
		this.start(); // this line starts child thread and call its run() method
		
		objx.firstX(objy); // this line is executed by main thread to call firstX() of class X
	}
	public void run()
	{
		objy.firstY(objx); // this line is executed by main thread to call firstY() of class Y		
	}
	
	public static void main(String[] args) 
	{
		// creating child thread named deadlock
		Deadlock d = new Deadlock();
		
		// calling startThread() function which will start() child thread
		d.startThread();
	}
}

In this program, we have two threads: main thread and child thread.

The main thread gets lock of objx and calls synchronized firstX() method on objx.

Simultaneously, the child thread gets lock of objy and calls synchronized firstY() method on objy.

Now, the main thread tries to call secondY() method on objy within the firstX() method and concurrently, child thread tries to call secondX() method on objx within the firstY() method.

Since main thread possesses lock of objx and child thread possesses lock of objy, they end up waiting for infinite time to get lock of objy and objx respectively.

Thus, they will not be able to execute secondX() and secondY() methods. And program will enter into the deadlock situation.

Look at the output below for better understanding. It is evident from the output that the secondX() and secondY() method is never executed and both threads end up waiting for each other for an infinite amount of time.

Output:

Main Thread has started execution of firstX() method
Child Thread has started execution of firstY() method
Main Thread is trying to call secondY() method
Child Thread is trying to call secondX() method

In the above program, if we remove at least one synchronized keyword from any one of the four methods, then the program will never enter into deadlock.

Hence, synchronized keyword is the only reason for deadlocks. Due to this, it is not recommended to use synchronized keyword without special requirement.

Look at the following code where method secondY() is no more synchronized.

class X
{	
	public synchronized void firstX(Y objy)
	{
		System.out.println("Main Thread has started execution of firstX() method");
		try
		{	
			Thread.sleep(2000);
		}
		catch(InterruptedException exp)
		{
			System.out.println("Main Thread has been interrupted");
		}
		System.out.println("Main Thread is trying to call secondY() method");
		objy.secondY();
	}
	
	public synchronized void secondX()
	{
		System.out.println("secondX() method has been called");
	}
}

class Y
{	
	public synchronized void firstY(X objx)
	{
		System.out.println("Child Thread has started execution of firstY() method");
		try
		{	
			Thread.sleep(2000);
		}
		catch(InterruptedException exp)
		{
			System.out.println("Child Thread has been interrupted");
		}
		System.out.println("Child Thread is trying to call secondX() method");
		objx.secondX();	
	}
	
	public void secondY()
	{
		System.out.println("secondY() method has been called");		
	}
}

public class Deadlock extends Thread 
{
	X objx = new X();
	Y objy = new Y();
	
	public void startThread()
	{
		this.start(); // this line starts child thread and call its run() method
		
		objx.firstX(objy); // this line is executed by main thread to call firstX() of class X
	}
	public void run()
	{
		objy.firstY(objx); // this line is executed by main thread to call firstY() of class Y		
	}
	
	public static void main(String[] args) 
	{
		// creating child thread named deadlock
		Deadlock d = new Deadlock();
		
		// calling startThread() function which will start() child thread
		d.startThread();
	}
}

In this case, there will not be any deadlock situation and the program will complete its execution successfully.

Output:

Main Thread has started execution of firstX() method
Child Thread has started execution of firstY() method
Main Thread is trying to call secondY() method
secondY() method has been called
Child Thread is trying to call secondX() method
secondX() method has been called

Difference between Deadlock and Starvation

Long waiting of a thread where waiting never ends is called deadlock.

Whereas, long waiting of a thread where waiting ends at a certain point is called starvation.

For example, low priority thread has to wait until the completion of all high priority thread. This waiting which may be long or short, ends at a certain point. This is nothing but Starvation.

This is all about deadlock and starvation in Java. Hope you find this tutorial helpful.

Leave a Comment

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