Back to Thread Lifecycle: Priority, Interruption, Factory
Q3Question 3 of 5

Why are stop/suspend/resume deprecated?

Key Concepts
  • Thread.stop() throws ThreadDeath at an arbitrary instruction, releasing all monitors and leaving state inconsistent.
  • Thread.suspend() freezes the thread without releasing held locks, causing deadlock when the resuming thread needs one of those locks.
  • Thread.resume() is deprecated because it only pairs with the unusable suspend().
  • The correct replacement is cooperative interruption: interrupt() sets a flag, the worker checks it at safe points.
  • For pausing, use a guarded wait on a Condition that releases the lock while paused.
  • ThreadDeath is a Throwable that can be caught, leading to even weirder behaviour where a thread refuses to die.
  • Forced control over another thread's execution is never safe; cooperative signalling is the only correct approach.

Definition

stop leaves money half-moved and locks dropped, suspend freezes a thread holding locks and deadlocks everyone else: always use interrupt plus InterruptedException instead.
  • Thread.stop() – forcibly throws ThreadDeath at an arbitrary point, releasing all monitors and leaving shared objects in a half-updated state.
  • Thread.suspend() – freezes a thread without releasing its locks, so any thread needing those locks deadlocks.
  • Thread.resume() – deprecated because it only pairs with the unusable suspend().
  • Correct replacement – cooperative interruption with interrupt(), checking isInterrupted() at safe points, and handling InterruptedException.
  • For pausing – use Object.wait() on a condition, which releases the lock while paused.

Imagine a teller at National Bank of India is halfway through a transfer: she has debited Rajesh but not yet credited Priya. stop is like dragging her away mid-transfer and throwing her keys on the floor: money vanishes and the drawer is unlocked. suspend is like freezing her in place while she clutches the vault key, so every other teller is stuck. The safe way is to pass her a note saying "please stop when you have finished the current transfer."

Understanding the Concepts

Why is Thread.stop() dangerous?

It throws ThreadDeath at whatever instruction the thread is executing. If the thread is between debit and credit, stop fires after the debit and before the credit. As the thread unwinds it releases all monitors, so other threads see the corrupted state as valid.

JAVA
// The danger: stop fires between these two lines
synchronized (ledger) {
    rajesh.debit(amount);   // done
    // ← ThreadDeath thrown here
    priya.credit(amount);   // never executed
}   // lock released with inconsistent state

Why is Thread.suspend() dangerous?

It pauses the thread immediately but does not release any locks it holds. If the suspended thread holds the ledger lock and the resuming thread needs it, deadlock results.

JAVA
// Thread A holds the lock and is suspended
synchronized (ledger) {
    // ← suspended here, lock NOT released
}
// Thread B tries to acquire the same lock to call resume
synchronized (ledger) {  // DEADLOCK: lock held by frozen Thread A
    threadA.resume();
}

What is the correct replacement for stop?

Cooperative interruption. The controller calls interrupt(), the worker checks the flag only between complete operations.

JAVA
package com.bank.worker;

public class TransferWorker implements Runnable {

    @Override
    public void run() {
        while (!Thread.currentThread().isInterrupted()) {
            doOneTransfer();  // interruption can only take effect between transfers
        }
        System.out.println("Stopped between transfers, ledger is consistent.");
    }
}

What is the correct replacement for suspend/resume?

A guarded wait on a condition that releases the lock while paused.

JAVA
package com.bank.worker;

public class PausableWorker implements Runnable {

    private volatile boolean paused = false;
    private final Object pauseLock = new Object();

    public void pause() { paused = true; }

    public void resumeWork() {
        synchronized (pauseLock) {
            paused = false;
            pauseLock.notifyAll();
        }
    }

    @Override
    public void run() {
        while (!Thread.currentThread().isInterrupted()) {
            synchronized (pauseLock) {
                while (paused) {
                    try {
                        pauseLock.wait();  // releases the lock while paused
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        return;
                    }
                }
            }
            doOneTransfer();
        }
    }
}

What are the key differences?

| Method | Problem | Safe Replacement |
|--------|---------|------------------|
| stop() | Inconsistent state, released locks | interrupt() + check at safe point |
| suspend() | Deadlock: holds locks while frozen | wait() releases lock while paused |
| resume() | Only pairs with broken suspend() | notifyAll() |

What should a senior engineer know?

ThreadDeath is a Throwable that can be caught, leading to even weirder behaviour where a thread refuses to die. Forced control over another thread is never safe; cooperative signalling is the only correct approach.

What are common interview follow-up questions?

  • Can ThreadDeath be caught to prevent stopping?
  • How does ExecutorService.shutdownNow() use interrupt instead of stop?
  • What happens if you call stop on a thread that has already exited?

Visual Overview

DIAGRAM
  Thread.stop():
  ┌──────────────────────────────────┐
  │ synchronized (ledger) {          │
  │   rajesh.debit(50000);  ✓ done   │
  │   ←── ThreadDeath thrown here ──▶│ lock released
  │   priya.credit(50000);  ✗ skip  │
  │ }                                │
  └──────────────────────────────────┘
  Result: Rs.50000 vanished, ledger inconsistent

  Thread.suspend():
  ┌──────────────────────────────────┐
  │ Thread A: synchronized (ledger)  │
  │   ←── suspended, lock NOT freed  │
  │                                  │
  │ Thread B: synchronized (ledger)  │
  │   ←── BLOCKED forever (deadlock) │
  └──────────────────────────────────┘

  Correct: cooperative interrupt
  ┌──────────────────────────────────┐
  │ while (!isInterrupted()) {       │
  │   doOneTransfer();  // safe point│
  │ }                                │
  │ // stops only between transfers  │
  └──────────────────────────────────┘

Key Takeaway

Thread.stop, suspend, and resume are deprecated because they are inherently unsafe. Stop throws ThreadDeath at an arbitrary point and releases all monitors, leaving shared state inconsistent. Suspend freezes a thread without releasing its locks, causing deadlock.

The correct replacement is cooperative interruption. The controller calls interrupt(), and the worker checks the flag only between complete operations, so a stop can only take effect at a safe point. For pausing, use a guarded wait that releases the lock while paused.

At National Bank of India we inherited a worker killed with stop that left the ledger out of balance. The fix checked the interrupt flag only between complete transfer pairs, and a wait-based pause released the lock properly.

Remember one sentence: forced control over another thread is never safe, so signal with interrupt and let the thread stop itself at a point where its state is consistent.

---

Share
Use ← → arrow keys to navigate