A deadlock occurs when two or more threads are blocked forever, each waiting for a resource (lock) held by another thread. None of the threads can continue execution, causing the program to freeze.
Deadlock = circular waiting + no thread can proceed
A deadlock occurs when all of the following are true:
- Mutual Exclusion – resources cannot be shared
- Hold and Wait – a thread holds one lock and waits for another
- No Preemption – locks cannot be forcibly taken
- Circular Wait – thread A waits for B, B waits for C, C waits for A
If even one condition is broken → deadlock cannot occur.
class DeadlockExample {
private final Object lock1 = new Object();
private final Object lock2 = new Object();
public void method1() {
synchronized (lock1) {
System.out.println("Thread 1: Holding lock1...");
try { Thread.sleep(100); } catch (Exception e) {}
synchronized (lock2) {
System.out.println("Thread 1: Holding lock1 & lock2...");
}
}
}
public void method2() {
synchronized (lock2) {
System.out.println("Thread 2: Holding lock2...");
try { Thread.sleep(100); } catch (Exception e) {}
synchronized (lock1) {
System.out.println("Thread 2: Holding lock2 & lock1...");
}
}
}
}
public class Demo {
public static void main(String[] args) {
DeadlockExample obj = new DeadlockExample();
Thread t1 = new Thread(() -> obj.method1());
Thread t2 = new Thread(() -> obj.method2());
t1.start();
t2.start();
}
}t1acquireslock1and waits forlock2t2acquireslock2and waits forlock1- Both wait forever → deadlock
Always acquire locks in the same order.
It attempts acquiring a lock without blocking forever.
if(lock.tryLock(100, TimeUnit.MILLISECONDS)) { ... }Keep critical sections short.
java.util.concurrentlocks- Executors
- Synchronized queues
- Semaphores
Use:
jstack <pid>
These methods existed in early Java versions but were deprecated because they are unsafe and can lead to serious concurrency issues.
thread.stop();The thread:
- Does NOT release locks
- Does NOT complete critical sections
- May leave shared objects in corrupted states
Example scenario:
Thread acquires a lock → modifies object → stop() kills it → lock never released → deadlock
If a thread is updating a shared list, and stop() interrupts halfway:
- List may become partially updated
- Other threads may crash
Use a flag to stop threads gracefully.
class MyTask implements Runnable {
private volatile boolean running = true;
public void stop() { running = false; }
public void run() {
while (running) {
// task logic
}
}
}Pauses a thread without releasing locks.
Resumes a suspended thread.
If a thread suspended itself in a synchronized block:
synchronized(obj) {
thread.suspend(); // locks never released!
}- Other threads waiting for
obj→ blocked forever → deadlock
If you call suspend() at the wrong moment:
- The thread might be holding a critical resource
- Entire application can freeze
Since the caller cannot know what the thread is doing, it's unsafe.
If a thread is not suspended but you call resume():
- Nothing happens (no error)
- Logic becomes unpredictable
If resume() is lost before the thread suspends → thread stays suspended forever.
Use:
wait() / notify()LockSupport.park()/unpark()- Conditions (
ReentrantLock.newCondition())
Example using wait/notify:
synchronized (lock) {
lock.wait(); // replaces suspend()
}synchronized (lock) {
lock.notify(); // replaces resume()
}| Method | Reason for Deprecation |
|---|---|
stop() |
Causes inconsistent object states, breaks synchronization, can corrupt memory |
suspend() |
Suspends threads while holding locks → causes deadlocks |
resume() |
Can be called at wrong time → thread may remain suspended forever |
| Combined effect | Unpredictable behavior, deadlocks, race conditions |
| Old Method | Modern Safe Alternative |
|---|---|
stop() |
Graceful termination with flags (volatile boolean) |
suspend() |
wait(), LockSupport.park() |
resume() |
notify(), LockSupport.unpark() |
These alternatives ensure the thread:
- Releases locks
- Completes critical operations
- Does not corrupt shared memory
Two or more threads waiting for each other forever, causing the program to freeze.
When multiple threads acquire locks in different orders, creating circular dependency.
- Consistent lock order
- Use
tryLock() - Reduce synchronized scope
- Avoid nested locks
It kills a thread immediately without releasing locks, leaving objects in inconsistent states.
suspend() suspends a thread while holding locks → deadlocks.
resume() doesn’t ensure correct resume timing → unpredictable behavior.
Use a volatile boolean flag or interrupt mechanism.
Yes, using tools like:
jstack <pid>
-
Deadlocks occur due to circular wait and improper lock handling
-
stop(),suspend(), andresume()are unsafe and cause deadlocks or memory corruption -
Modern Java uses interrupts, wait/notify, LockSupport, and thread pools
-
Avoid forcing threads to stop or suspend abruptly
-
Always design thread-safe and lock-safe code