Java Deadlock Example and Solution

Learn to create a deadlock in Java, programmatically, with an example. Also learn to detect deadlock and how to solve a deadlock situation in sourcecode.

In my previous post, I written about auto reload of configuration when any change happen in property files, I discussed about refreshing your application configuration using Java WatchService. As configurations are shared resources and when accessing via Threads, there is always chance of writing incorrect code which can cause in deadlock situation.

1. Deadlock

In Java, a deadlock is a situation where minimum two threads are holding the lock on some different resource, and both are waiting for other’s resource to complete its task. And, none is able to leave the lock on the resource it is holding.

deadlock scenario
Deadlock Scenario

In above case, Thread-1 has A but need B to complete processing and similarly Thread-2 has resource B but need A first.

package thread;

public class ResolveDeadLockTest {

	public static void main(String[] args) {
		ResolveDeadLockTest test = new ResolveDeadLockTest();

		final A a = test.new A();
		final B b = test.new B();

		// Thread-1
		Runnable block1 = new Runnable() {
			public void run() {
				synchronized (a) {
					try {
						// Adding delay so that both threads can start trying to
						// lock resources
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					// Thread-1 have A but need B also
					synchronized (b) {
						System.out.println("In block 1");
					}
				}
			}
		};

		// Thread-2
		Runnable block2 = new Runnable() {
			public void run() {
				synchronized (b) {
					// Thread-2 have B but need A also
					synchronized (a) {
						System.out.println("In block 2");
					}
				}
			}
		};

		new Thread(block1).start();
		new Thread(block2).start();
	}

	// Resource A
	private class A {
		private int i = 10;

		public int getI() {
			return i;
		}

		public void setI(int i) {
			this.i = i;
		}
	}

	// Resource B
	private class B {
		private int i = 20;

		public int getI() {
			return i;
		}

		public void setI(int i) {
			this.i = i;
		}
	}
}

Running above code will result in a deadlock for very obvious reasons (explained above). Now we have to solve this issue.

2. How to avoid deadlock

I believe, the solution to any problem lies in identifying the root of the problem. In our case, it is the pattern of accessing the resources A and B, is main issue. So, to solve it, we will simply re-order the statements where the code is accessing shared resources.

       // Thread-1
	Runnable block1 = new Runnable() {
		public void run() {
			synchronized (b) {
				try {
					// Adding delay so that both threads can start trying to
					// lock resources
					Thread.sleep(100);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				// Thread-1 have A but need B also
				synchronized (a) {
					System.out.println("In block 1");
				}
			}
		}
	};

	// Thread-2
	Runnable block2 = new Runnable() {
		public void run() {
			synchronized (b) {
				// Thread-2 have B but need A also
				synchronized (a) {
					System.out.println("In block 2");
				}
			}
		}
	};

Run again above class, and you will not see any deadlock kind of situation. I hope, it will help you in avoiding deadlocks, and if encountered, in resolving them.

Happy Learning !!

Was this post helpful?

Join 7000+ Fellow Programmers

Subscribe to get new post notifications, industry updates, best practices, and much more. Directly into your inbox, for free.

16 thoughts on “Java Deadlock Example and Solution”

  1. Great explanation but 100% deadlock here is still NOT guaranteed as in case where thread-1 completes its run() calling before thread-0 initiates its call to its run(). Its all depend on CPU scheduler.

  2. Hi Lokesh,

    Great Explanation!

    Can we achieve dead lock using Class Level Locking instead of using object level locking?

  3. Hi,
    I have a project about make deadlock and solve it.But i do not know about what should i do for my projects.
    please help me.

  4. Hey Lokesh,
    What if the resources that are locked are passed as parameters by threads , that is a & b are passed as parameters and one thread passes x & y to a, b and the other passes y & x. Can you talk about that scenario if possible. Thanks.

    • In such scenario, you can use any type of ordering on a and b e.g. Object.identityHashCode() can be used to compare any type of object and based on that comparison you can decide the lock order.

  5. Basic Factors for Deadlock

    1) Mutual Exclusion
    2) Hold and Wait
    3) No Preemption
    4) Circular Wait

  6. Thanks for this article.
    I had to design “Resource Manager” application for a multi-user system. This Resource Manager should monitor the requests made by the users (or processes) on resources of the system.
    i got some basic idea through this article.

  7. Hello!
    Why have you made resourses as internal classes? I tryed to create two Integer-reference objects and they do the same work perfectly. In my opinion, example without these internal classes looks clearer. Do you have some special meaning for this solution?
    In any case, thank you for good explanations!

  8. Loved your approach of getting to the root problem by first understanding the pattern. Youd rocked it!

Comments are closed.

HowToDoInJava

A blog about Java and its related technologies, the best practices, algorithms, interview questions, scripting languages, and Python.