Java Programs›Multithreading›Stop a Thread Using a volatile Flag

Stop a Thread Using a volatile Flag in Java

intermediate·  Multithreading  ·  Concurrency

Problem

volatile guarantees that a write to a variable by one thread is immediately visible to every other thread that reads it.

Start a worker that loops until told to stop, then stop it cleanly from the main thread.

Input
main sets running = false after 100 ms
Output
worker exits, alive = false

Java Program

Java
public class VolatileStopFlag { private static volatile boolean running = true; // writes are seen by every thread immediately public static void main(String[] args) throws InterruptedException { Thread worker = new Thread(() -> { while (running) { // re-reads the volatile flag on every check Thread.onSpinWait(); } System.out.println("Worker saw the stop request and exited"); }); worker.start(); Thread.sleep(100); // let it spin for a moment running = false; // ask it to stop worker.join(2000); System.out.println("Worker still alive: " + worker.isAlive()); } }

Output

Worker saw the stop request and exited Worker still alive: false

Core Logic

The worker checks a shared flag on every loop iteration, and volatile makes sure it sees main's update.

How It Works
  1. 1running is a static volatile boolean that starts as true.
  2. 2The worker loops while running is true.
  3. 3Main sleeps briefly, then sets running = false.
  4. 4join(2000) waits for the worker, and isAlive() confirms it stopped.
Within moments of the flag changing, the worker leaves its loop and prints its exit message.
💡

Key Point: Without volatile, the JIT compiler may hoist the flag read out of the loop, so the worker can spin forever without ever noticing the change.

Key Concepts

volatilevisibilitycooperative cancellationjoin(timeout)

Approach 2: Using AtomicBoolean

Java
import java.util.concurrent.atomic.AtomicBoolean; public class VolatileStopAtomic { public static void main(String[] args) throws InterruptedException { AtomicBoolean running = new AtomicBoolean(true); Thread worker = new Thread(() -> { while (running.get()) { Thread.onSpinWait(); // hint to the CPU that this is a busy-wait loop (Java 9+) } System.out.println("Worker stopped"); }); worker.start(); Thread.sleep(100); boolean changed = running.compareAndSet(true, false); // only succeeds if it was still true worker.join(2000); System.out.println("Stop request applied: " + changed); System.out.println("Worker still alive: " + worker.isAlive()); } }

Output

Worker stopped Stop request applied: true Worker still alive: false

Core Logic

AtomicBoolean gives the same visibility as volatile, plus atomic operations such as compare-and-set.

How It Works
  1. 1The worker loops while running.get() is true.
  2. 2compareAndSet(true, false) stops it and reports whether this call made the change.
  3. 3Thread.onSpinWait() tells the CPU the loop is a busy-wait.
compareAndSet returns true because the flag was still true when main changed it.
💡

Key Point: volatile gives visibility but not atomicity; use atomics when a check-then-update must happen as one step.

Key Concepts

AtomicBooleancompareAndSet()Thread.onSpinWait()

Interview Questions

Why is Thread.stop() deprecated?

It kills a thread at any point, releasing its locks while data may be half-updated. Cooperative flags or interruption let the thread stop at a safe point.

Does volatile make count++ thread-safe?

No. volatile makes reads and writes visible, but count++ is a read, an add and a write that other threads can interleave.

Learn the Concept

Related Programs