Core Java

Java Deadlock Example

In this article, we are going to show a Deadlock example in Java.

1. Introduction

In Java deadlock is defined as a scenario where two or more threads are blocked forever. A computer system normally has many active processes and threads. This is true even in systems that only have a single execution core, and thus only have one thread actually executing at any given moment. Processing time for a single core is shared among processes and threads through an OS feature called time slicing.

Java Deadlock

Threads are sometimes called lightweight processes. Both processes and threads provide an execution environment, but creating a new thread requires fewer resources than creating a new process. Threads exist within a process. Every process has at least one. Threads share the process’s resources, including memory and open files. This makes for efficient, but potentially problematic, communication.

2. Java Deadlock Example

In this section, we will see how to create a scenario where a deadlock can happen. We will create two lock objects which we will use for locking.

private static Object lock1 = new Object();
private static Object lock2 = new Object();

We will start by creating a simple Thread.

Thread1.java

private static class Thread1 extends Thread {

    @Override
    public void run() {
        synchronized (lock1) {
            System.out.println("Thread1 is holding lock1");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
            }
            System.out.println("Thread1 is trying to obtain lock2...");
            synchronized (lock2) {
                System.out.println("Thread1 is holding lock2");
            }
        }
    }
}

The first thing this thread will do is get a lock on lock1 object synchronized (lock1). Then we will let the sleep for 100 ms. After that this thread will try to get a lock on lock2 object.

Now we will see how the second Thread class looks like.

Thread2.java

private static class Thread2 extends Thread {

    @Override
    public void run() {
        synchronized (lock2) {
            System.out.println("Thread2 is holding lock2");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {

            }

            System.out.println("Thread2 is trying to obtain lock1...");
            synchronized (lock1) {
                System.out.println("Thread2 is holding lock1");
            }
        }
    }
}

As we can see here that the second thread first tries to get a lock on lock2 object then sleep for 100 ms then try to get a lock on lock1 object. The sequence of getting the lock is opposite to Thread1.

Now let us see how the main method looks like:

public static void main(String[] args) {
    Thread1 thread1 = new Thread1();
    Thread2 thread2 = new Thread2();
    thread1.start();
    thread2.start();
}

So when we run this class there is a good chance we will end up in a deadlock. Thread1 will get the lock on lock1 object then goes to sleep. Before it is awake thread2 will get a lock on lock2. Now when thread1 awakes it will try to get the lock on lock2 object but thread2 is holding that lock. Thread2 can’t release the lock on lock2 as to do that it needs to get a lock on lock1 object which is locked by thread1.

So both the threads are waiting for the locks which the other thread has. So we have a deadlock situation here.

DeadlockExample.java

public class DeadlockExample {

    private static Object lock1 = new Object();
    private static Object lock2 = new Object();

    public static void main(String[] args) {
        Thread1 thread1 = new Thread1();
        Thread2 thread2 = new Thread2();
        thread1.start();
        thread2.start();
    }

    private static class Thread1 extends Thread {

        @Override
        public void run() {
            synchronized (lock1) {
                System.out.println("Thread1 is holding lock1");
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {

                }

                System.out.println("Thread1 is trying to obtain lock2...");
                synchronized (lock2) {
                    System.out.println("Thread1 is holding lock2");
                }
            }
        }
    }

    private static class Thread2 extends Thread {

        @Override
        public void run() {
            synchronized (lock2) {
                System.out.println("Thread2 is holding lock2");
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {

                }

                System.out.println("Thread2 is trying to obtain lock1...");
                synchronized (lock1) {
                    System.out.println("Thread2 is holding lock1");
                }
            }
        }
    }
}

When you will run this class you will se an output like below:

Thread2 is holding lock2
Thread1 is holding lock1
Thread2 is trying to obtain lock1...
Thread1 is trying to obtain lock2...

If you do a thread dump you will see that the state of the treads are blocked

Thread0 dump:

"Thread-0" #12 prio=5 os_prio=31 cpu=0.99ms elapsed=4.79s tid=0x00007fd5a886b000 nid=0x9a03 waiting for monitor entry  [0x000070000e2a2000]
   java.lang.Thread.State: BLOCKED (on object monitor)
	at com.javacodegeeks.DeadlockExample$Thread1.run(DeadlockExample.java:29)
	- waiting to lock  (a java.lang.Object)
	- locked  (a java.lang.Object)

Thread1 dump:

"Thread-1" #13 prio=5 os_prio=31 cpu=0.66ms elapsed=4.79s tid=0x00007fd5aa009000 nid=0x9703 waiting for monitor entry  [0x000070000e3a5000]
   java.lang.Thread.State: BLOCKED (on object monitor)
	at com.javacodegeeks.DeadlockExample$Thread2.run(DeadlockExample.java:49)
	- waiting to lock  (a java.lang.Object)
	- locked  (a java.lang.Object)


3. Summary

In this article, we learned what is a deadlock and how it can occur in Java. We also learned how a Thread is different from a Process. Finally, we showed a working example where we created a scenario where a deadlock can occur.

4. Download the Source Code

This was an example of Java Deadlock.

Download
You can download the full source code of this example here: Java Deadlock Example

Mohammad Meraj Zia

Senior Java Developer
Subscribe
Notify of
guest

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

0 Comments
Inline Feedbacks
View all comments
Back to top button