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+ Awesome Developers

Get the latest updates from industry, awesome resources, blog updates and much more.

* We do not spam !!

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.

    Reply
  2. 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.

    Reply
    • 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.

      Reply
  3. 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.

    Reply
  4. 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!

    Reply

Leave a Comment

HowToDoInJava

A blog about Java and related technologies, the best practices, algorithms, and interview questions.