Deadlock defintion
Deadlock is a situation that can occur when two or more threads are blocked indefinitely trying to obtain access to a resource locked by the other threads in the deadlock. Thus, the deadlocked threads are blocked, waiting for each other to release a resource which neither of them can release because they are blocked waiting for the other thread to release its resource first.
Such resources can be Java Locks, Java synchronized blocks (Java monitor objects), files, database tables and / or records etc.

Deadlock code example using two Lock instances in Java
public class DeadLockExample { public static void main(String[] args) { Lock lock1 = new ReentrantLock(); Lock lock2 = new ReentrantLock(); Thread thread1 = new Thread(new Runnable1(lock1, lock2)); Thread thread2 = new Thread(new Runnable2(lock1, lock2)); thread1.start(); thread2.start(); } }
public class Runnable1 implements Runnable{ private Lock lock1 = null; private Lock lock2 = null; public Runnable1(Lock lock1, Lock lock2) { this.lock1 = lock1; this.lock2 = lock2; } @Override public void run() { String threadName = Thread.currentThread().getName(); System.out.println(threadName+ " attempt to lock Lock1"); lock1.lock(); System.out.println(threadName+ " lock Lock1"); try { sleep(3000); } catch (InterruptedException e) { } System.out.println(threadName+ " attempt to lock Lock2"); lock2.lock(); System.out.println(threadName+ " lock Lock2"); //do the work - 두 lock 모두 lock함 //unlock System.out.println(threadName+ " unlock Lock1"); lock1.unlock(); System.out.println(threadName+ " unlock Lock2"); lock2.unlock(); } }
public class Runnable2 implements Runnable{ private Lock lock1 = null; private Lock lock2 = null; public Runnable2(Lock lock1, Lock lock2) { this.lock1 = lock1; this.lock2 = lock2; } @Override public void run() { String threadName = Thread.currentThread().getName(); System.out.println(threadName+ " attempt to lock Lock2"); lock2.lock(); System.out.println(threadName+ " lock Lock2"); try { sleep(3000); } catch (InterruptedException e) { } System.out.println(threadName+ " attempt to lock Lock1"); lock1.lock(); System.out.println(threadName+ " lock Lock1"); //unlock System.out.println(threadName+ " unlock Lock1"); lock1.unlock(); System.out.println(threadName+ " unlock Lock2"); lock2.unlock(); } }
실행결과 - unlock 안함 (그림의 상황)
Thread-1 attempt to lock Lock2 Thread-0 attempt to lock Lock1 Thread-0 lock Lock1 Thread-1 lock Lock2 Thread-0 attempt to lock Lock2 Thread-1 attempt to lock Lock1
Deadlock code example using two synchronized blocks in Java
public class DeadLockSyncExample { public static void main(String[] args) { Lock lock1 = new ReentrantLock(); Lock lock2 = new ReentrantLock(); Thread thread1 = new Thread(new RunnableSync1(lock1, lock2)); Thread thread2 = new Thread(new RunnableSync2(lock1, lock2)); thread1.start(); thread2.start(); } }
public class RunnableSync1 implements Runnable{ private Object lock1 = null; private Object lock2 = null; public RunnableSync1(Lock lock1, Lock lock2) { this.lock1 = lock1; this.lock2 = lock2; } @Override public void run() { String threadName = Thread.currentThread().getName(); System.out.println(threadName+ " attempt to lock Lock1"); synchronized (lock1) { System.out.println(threadName + " lock Lock1"); try { sleep(3000); } catch (InterruptedException e) { } System.out.println(threadName + " attempt to lock Lock2"); synchronized (lock2){ System.out.println(threadName + " lock Lock2"); //do the work - 두 lock 모두 lock함 System.out.println(threadName + " unlock Lock2"); } System.out.println(threadName + " unlock Lock1"); } } }
public class RunnableSync2 implements Runnable{ private Object lock1 = null; private Object lock2 = null; public RunnableSync2(Lock lock1, Lock lock2) { this.lock1 = lock1; this.lock2 = lock2; } @Override public void run() { String threadName = Thread.currentThread().getName(); System.out.println(threadName+ " attempt to lock Lock2"); synchronized (lock2) { System.out.println(threadName + " lock Lock2"); try { sleep(3000); } catch (InterruptedException e) { } System.out.println(threadName + " attempt to lock Lock1"); synchronized (lock1){ System.out.println(threadName + " lock Lock1"); //do the work - 두 lock 모두 lock함 System.out.println(threadName + " unlock Lock1"); } System.out.println(threadName + " unlock Lock2"); } } }
- 여기도 데드락 걸림
Deadlock can occur with any mutually exclusive access / lockable resource
- 데드락은 여러 쓰레드가 접근해서 락을 거는 어떠한 리소스에도 터질 수 있다.
Deadlock fix via lock ordering
- lock 접근 순서를 둘다 lock1, lock2로 함 → 데드락 안걸림
More complex deadlock scenario

e.g. DB 테이블 락, 파일 락 등등
A deadlock will block all threads trying to lock a resource involved in the deadlock

- 데드락에 접근하는 새로운 쓰레드들은 block된다.
The four conditions required for a deadlock to occur
- Mutual Exclusion
- No Preemption
- Hold and Wait
- Circular Wait
Other problems similar to deadlock
- Livelock
- Nested Moniter Lockout
- Reentrance lockout
- Starvation