Back to Thread Lifecycle: Priority, Interruption, Factory
Q2Question 2 of 5

What is cooperative interruption?

Key Concepts
  • interrupt() sets the target thread's interrupt status flag to true; it does not stop the thread.
  • isInterrupted() reads the flag without changing it; use it to poll inside a loop.
  • Thread.interrupted() (static) reads the flag and clears it; use it only when consuming the signal.
  • Blocking methods (sleep, wait, join, take) throw InterruptedException and clear the flag.
  • Swallowing InterruptedException without restoring the flag or stopping is a common concurrency bug.
  • Cooperative interruption lets the thread stop at a safe point, avoiding inconsistent state and held locks.
  • Future.cancel(true) and shutdownNow() use interrupt under the hood.

Definition

interrupt() raises a flag, the thread checks the flag at safe points and decides to stop: it is a polite request, not a forced stop.
  • interrupt() – sets the target thread's internal interrupt status flag to true; does not stop the thread.
  • isInterrupted() – instance method that reads the flag without changing it; safe to poll in a loop.
  • Thread.interrupted() – static method that reads the flag and clears it; use only when consuming the interruption.
  • InterruptedException – thrown by blocking methods (sleep, wait, join, take) when the flag is set; clears the flag as part of throwing.
  • Cooperative – the target thread decides when and how to respond, avoiding inconsistent state and held locks.

Imagine Priya is running a long end-of-day report at National Bank of India, and the manager wants her to stop so the branch can close. The manager does not yank the report mid-calculation. Instead the manager raises a small flag on Priya's desk that says "please wrap up when you reach a safe point." Priya glances at the flag between pages, finishes the current page, saves her work, and stops.

Understanding the Concepts

What does interrupt() do?

When the target is running normally, interrupt() sets the interrupt status flag to true. Nothing is forced; the worker keeps running until it checks the flag.

JAVA
Thread worker = new Thread(() -> settleTradesLoop());
worker.start();
// Later, ask the worker to finish early:
worker.interrupt();  // sets the flag, does not stop the thread

What is the difference between isInterrupted() and interrupted()?

The instance method isInterrupted() returns the flag and leaves it unchanged. The static Thread.interrupted() returns the flag and clears it.

JAVA
// Poll without clearing:
while (!Thread.currentThread().isInterrupted()) {
    processNextTrade();
}

// Consume and handle:
if (Thread.interrupted()) {
    cleanup();
    return;
}

A classic bug is calling the static interrupted() when you meant to only check, because it silently wipes the flag.

How do blocking methods respond to interruption?

If a thread is parked in sleep, wait, join, or BlockingQueue.take when interrupted, the method throws InterruptedException and clears the flag.

JAVA
try {
    Thread.sleep(5000);
} catch (InterruptedException e) {
    // Flag was cleared by the throw
    Thread.currentThread().interrupt();  // restore the flag!
    return;
}

Swallowing InterruptedException without restoring the flag or stopping is one of the most common concurrency bugs.

What is the correct loop pattern?

JAVA
package com.bank.worker;

import java.math.BigDecimal;
import java.util.concurrent.BlockingQueue;

public class SettlementWorker implements Runnable {

    private final BlockingQueue<Trade> queue;

    public SettlementWorker(BlockingQueue<Trade> queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        while (!Thread.currentThread().isInterrupted()) {
            try {
                Trade trade = queue.take();  // blocking call
                settle(trade);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();  // restore flag
                break;  // exit the loop cleanly
            }
        }
        System.out.println("Worker stopped cleanly.");
    }

    private void settle(Trade trade) {
        // settlement logic
    }
}

Why is interruption cooperative, not forced?

A thread may be holding locks, may be halfway through updating two accounts in a transfer, or may own an open file. If the JVM forcibly killed it at an arbitrary instruction, it could leave shared state inconsistent. By making the thread choose a safe point, Java guarantees cancellation happens only where the code is in a consistent state.

What are common mistakes?

JAVA
// WRONG: swallows the interruption signal
try {
    Thread.sleep(1000);
} catch (InterruptedException e) {
    // does nothing: cancellation signal is lost!
}

// CORRECT: restore the flag or stop
try {
    Thread.sleep(1000);
} catch (InterruptedException e) {
    Thread.currentThread().interrupt();  // preserve the signal
}

How do Future.cancel and shutdownNow use interrupt?

Future.cancel(true) interrupts the running task's thread. ExecutorService.shutdownNow() interrupts the pool's worker threads. Your tasks must be interruption-aware for a clean shutdown.

What are common interview follow-up questions?

  • How does ClosedByInterruptException work for NIO channels?
  • What happens if you interrupt a thread that is not blocking?
  • How do virtual threads handle interruption?

Visual Overview

DIAGRAM
  Thread A                          Thread B (worker)
  ─────────                         ────────────────
  worker.interrupt()  ──flag──▶     isInterrupted() == true
                                         │
                                    ┌────┴────────────────┐
                                    │ If running:          │
                                    │   check flag in loop │
                                    │   stop at safe point │
                                    │                      │
                                    │ If blocked (sleep/   │
                                    │   wait/take):        │
                                    │   InterruptedException│
                                    │   flag cleared       │
                                    │   catch → restore or │
                                    │           stop       │
                                    └──────────────────────┘

  isInterrupted()      interrupted()
  ─────────────────    ────────────────
  Reads flag           Reads flag
  Leaves unchanged     Clears it
  Poll in loop         Consume once

Key Takeaway

Interruption in Java is cooperative cancellation. The interrupt() method sets a flag and nothing more. The thread itself must notice the flag and decide at a safe point how to respond.

There are two ways to read the flag: isInterrupted() reads without clearing (for polling), and Thread.interrupted() reads and clears (for consuming). Blocking methods throw InterruptedException and clear the flag, so you must restore it or stop.

The reason it is cooperative is safety. A thread might be halfway through a transfer, holding locks, or owning a connection. Forced stopping could leave state inconsistent. Cooperative interruption lets the thread choose a safe checkpoint.

At National Bank of India our settlement workers use this model so deployments stop them cleanly: interrupt arrives, the blocked take call throws, the worker restores the flag, finishes its current trade, and exits.

Remember one sentence: interrupt() raises a flag, the thread checks it at a safe point, and cancellation is always a request the worker honours, never a kill it suffers.

---

Share
Use ← → arrow keys to navigate