How to detect and avoid deadlock in Java with example

This guide will help you understand the deadlock concept in Java. We will also take a look at ways to detect and avoid deadlock in Java using a few examples.

What you will learn:
– What is a deadlock in Java?
– Deadlock example
– How to detect a deadlock using an example.
– Best practice to avoid the deadlock in java.

A few more Multithreading Articles on Codedelay
Thread Basics
Race condition and Critical Section
What is a deadlock in Java?
What is ThreadLocal
ExecutorService with a few examples

What is Deadlock in Java

In the last tutorial, we have discussed race conditions and how to avoid race conditions using synchronization.

As we discussed we can use the synchronized method and block to lock a portion of the code.

In java, each object has a lock, and synchronization is a way to lock a method or code block so that at a time only one thread can access that method/block.

When a thread wants to execute a synchronized method it first tries to acquire the lock.

If another thread has already acquired the lock then this thread has to wait until another thread releases the lock.

Synchronization is good to prevent data inconsistency issues.

However, there is a problem with synchronization.

Suppose there are two threads ‘Thread-A’ and ‘Thread-B’.

Let’s assume that Thread-A has acquired the lock of Object-A and Thread-B has acquired the lock of Object-B.

Now assume that Thread-A which is executing Method-A wants to acquire the lock on Object-B however Thread-B already acquires the lock on Object-B.

Furthermore, Thread-B also wants to acquire the lock on Object-A, however, Thread-A has a lock on Object-A.

In this situation both threads Thread-A and Thread-B can’t finish their execution and will wait forever for the lock.

This condition is called as the Deadlock.

Deadlock in Java
Deadlock in Java

Let’s understand deadlock using a Java Example

Deadlock example in Java

In this example, we have created two threads t1 and t2.

t1 has acquired the lock of object1 and t2 has acquired the lock of the object2.

Now to process further t1 has to acquire the lock of object2.

Until t1 successfully gets object2 lock it will wait.

At the same time to process further t2 has to acquire the lock of object1.

And Until t2 successfully gets object1 lock it will wait.

This scenario is called a deadlock.

How to detect and avoid deadlock

Although it is not easy to detect and avoid deadlock compile time.

There are few ways to detect deadlock at runtime.

Let’s discuss a few ways to detect the deadlock.

Deadlock detection using ThreadMXBean

Once you already entered into deadlock condition then you can get further information about threads that are blocked due to deadlock.

Deadlock detection in Java using ThreadMXBean
Deadlock detection in Java using ThreadMXBean

ThreadMxBean is an interface in java.lang.management .

ThreadMxBean is a management interface of JVM’s thread system.

As you could see in the above example we are calling findMonitorDeadlockedThreads from the ThreadMXBean instance.

findMonitorDeadlockedThreads returns threads information that are currently in deadlock (waiting to acquire locks).

findMonitorDeadlockedThreads
findMonitorDeadlockedThreads

Let me show you a complete example and output.

Output of the above program would be

How to avoid Deadlock

Deadlocks are bad.

Your complete application stops working once it faces a deadlock condition.

Moreover, when you get deadlock condition in a production application, then it is not just hard to troubleshoot but also very difficult to fix them.

However, you can avoid deadlocks by taking care of a few steps.

  1. Try to avoid nested synchronization blocks.
    In nested synchronization block one thread try to acquire another lock when it is already holding one lock.
  2. Lock ordering: If you can’t avoid nested synchronization block then you should make sure that threads will acquire locks in the same order. In the above example, one thread firstly acquired the lock on object1 and then tried to acquire an object2 lock.
    However, thread t2 acquired object2 lock first then tried to acquire the lock of object1.
    Hence deadlock occurred.
  3. Lock Timeout: You can also specify a timeout.
    If a thread fails to acquire a lock then it should wait for a specific time before retry to acquire the lock.

Conclusion

In this tutorial, we discussed Deadlock in Java, how to detect deadlock and how to avoid them with a few examples.

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.