JavaRush /Java Blog /Random EN /What is Deadlock in Java?
Alexey Smirnov
Level 29
Москва

What is Deadlock in Java?

Published in the Random EN group
Level of knowledge required to understand the article: you have completed the Java Syntax and Java Core quests, and are now in the process of learning Java Multithreading. Deadlock or deadlock in Java or deadlock is an error that occurs when threads have a cyclic dependency on a pair of synchronized objects. Imagine that one thread goes into the object monitor x, and the other goes into the object monitor y. If a thread in an object xtries to call any synchronized method on the object y, and the object yat the same time tries to call any synchronized method on the object x, the threads will get stuck waiting. What is Deadlock?  - 1Below is an example from the java docs tutorial about such a concept as deadlock. Where does thread blocking occur here?
public class Deadlock {
    static class Friend {
        private final String name;
        public Friend(String name) {
            this.name = name;
        }
        public String getName() {
            return this.name;
        }
        public synchronized void bow(Friend bower) {
            System.out.format("%s: %s" + "  has bowed to me!%n", this.name, bower.getName());
            bower.bowBack(this);
        }
        public synchronized void bowBack(Friend bower) {
            System.out.format("%s: %s"
                + " has bowed back to me!%n",
                this.name, bower.getName());
        }
    }

    public static void main(String[] args) {
        final Friend alphonse =
            new Friend("Alphonse");
        final Friend gaston =
            new Friend("Gaston");
        new Thread(new Runnable() {
            @Override
            public void run() {
               // System.out.println("Thread 1");
                alphonse.bow(gaston);
               // System.out.println("Th: gaston bowed to alphonse");
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
              //  System.out.println("Thread 2");
                gaston.bow(alphonse);
              //  System.out.println("2.gaston waiting alph bowed");
            }
        }).start();
    }
}
There are two important things to understand here:
  1. What exactly does each of the concurrently running threads do?
  2. What locks are used?
Let's start from the end. Let's say you created two objects of the class Friend: alphonseand gaston. Each of them has its own lock. Thus, there are two of these locks: gigolos and gastons. When a synchronized method of an object is entered, its lock is locked, and when the method is exited, it is released (or unlocked). Now about the threads. Let's call the first thread Alphonse(with a capital letter to distinguish it from the object alphonse). Here's what it does (let's call it A, short for Alphonse):
A: alphonse.bow(gaston) — получает лок alphonse;
A: gaston.bowBack(alphonse) — получает лок gaston;
A: возвращается из обоих методов, тем самым освобождая лок.
And here's what the thread is doing at this time Gaston:
G: gaston.bow(alphonse) — получает лок gaston;
G: alphonse.bowBack(gaston) — получает лок alphonse;
G: возвращается из обоих методов, тем самым освобождая лок.
Now let's put this data together and get the answer. Threads can be intertwined (that is, their events will occur) in different orders. A deadlock will work, for example, if the order is as follows:
A: alphonse.bow(gaston) — получает лок alphonse
G: gaston.bow(alphonse) — получает лок gaston
G: пытается вызвать alphonse.bowBack(gaston), но блокируется, ожидая лока alphonse
A: пытается вызвать gaston.bowBack(alphonse), но блокируется, ожидая лока gaston
What is Deadlock?  - 2
In this case, both threads are blocked and each is waiting for the other to release the lock. But none of them will do this, because to do this they need to complete their method, and it is blocked by another thread. So they were stuck where it happened deadlock. However, another weave is also possible, in which one of the threads will have time to complete before the second begins:
A: alphonse.bow(gaston) — получает лок alphonse
A: gaston.bowBack(alphonse) — получает лок gaston
A: возвращается из обоих методов, открывая оба лока
G: gaston.bow(alphonse) — получает лок gaston
G: alphonse.bowBack(gaston) — получает лок alphonse
G: возвращается из обоих методов, открывая оба лока
In this case, there is no mutual blocking of threads. For example, some method has been added that allows another thread to have time to execute. When the result depends on the order of simultaneously occurring events (planned order or speed of execution), such a process is called race condition in Russian - “race condition”. Not all race conditions potentially cause a deadlock, however, in my experience, only race conditions cause deadlocks. Posted by: Dave Lillethun
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION