Course contents

Thread basics: interview questions & scenarios

Premium20 questions · 27 what-if follow-ups

These are the thread basics questions I ask most often, roughly in the order I ask them: they start as warm-ups and turn into "what does the thread dump say?" and "how would you stop it?" within five minutes. Every answer here is correct for Java 21, and I flag it where an older or newer JDK behaves differently.

Here's how to use this page: read the question, answer it out loud first, then open the model answer. Don't skip the "What if…" chains. That's where most candidates run out of road, and where you can show real depth. If an answer feels thin, the lessons go deeper: Processes vs threads, Creating threads: Thread, Runnable and Callable, Thread lifecycle and states, Daemon threads and priorities and Interrupts and cancellation.

Question 1. ConceptWarm-up

What's the difference between a process and a thread? What do threads in the same JVM share?

Tests process isolation, shared heap, thread-private memory, static fields

Show answerHide answer3 follow-ups

Model answer

A process is a running program with its own address space, given to it by the OS. java Main creates one process holding one JVM, and nothing in it is visible to another process unless you go through a socket, a pipe, a file or shared memory. A thread is a path of execution inside a process, and it's the unit the OS scheduler puts on a core. Every Java program starts with at least the main thread plus a handful of JVM threads (GC, JIT compiler, Reference Handler, Finalizer and so on).

What threads in one JVM share and keep private:

Shared by all threads Private to each thread
The heap: every object and array JVM stack: one frame per method call, holding local variables and the operand stack
Static fields pc register (which bytecode it's on)
Metaspace (class metadata) and the code cache (JIT-compiled code) Native stack (for JNI and the JVM's own C++ code)

Static fields live on the heap. In HotSpot they're stored with the class's java.lang.Class object (they moved out of PermGen in JDK 7), so every thread sees the same static field. Metaspace holds the class's metadata, not its static values. Local variables are the only thing guaranteed to be thread-confined, because they sit in the thread's own stack frame. The objects they point to are still on the shared heap.

How I’d say it in the interview

"A process is an isolated program with its own memory; a thread is a unit of execution inside it. Threads share the heap, so all objects and static fields, plus Metaspace and the code cache. Each thread keeps its own stack, pc register and native stack. That's why locals are thread-safe and fields aren't: two threads can reach the same object through the heap, but never each other's stack frames."

Signals depth

Saying static fields are on the heap, not in Metaspace, and that a local reference is private while the object it points to is not. Bonus: platform threads map 1:1 to OS threads, each with its own reserved stack (-Xss, 1 MB by default on Linux/x64, 2 MB on Apple silicon).

Red flags

"Each thread has its own heap", "static fields live on the stack" or "static fields are in PermGen/Metaspace". Also "processes are heavyweight, threads are lightweight" with nothing behind it.

Follow-ups interviewers ask next

  1. What if a local variable holds a reference to a new ArrayList? Is that list thread-safe?

    It's safe as long as the reference never escapes. The variable is in the thread's frame and the list is on the heap, but no other thread can reach the list. The moment you store it in a field, put it in a shared collection or pass it to another thread, it's shared and the usual rules apply. This idea is called stack confinement.

    1. What if you keep the value in a ThreadLocal instead? Where does it live?

      On the heap. Each Thread object holds a ThreadLocalMap, and the values sit in that map, so they're per-thread by reachability, not by memory region. That's also why ThreadLocal leaks in thread pools: the pool thread lives forever, so the value does too unless you call remove().

  2. What if two JVMs on the same machine need to share data?

    They can't share a heap. You use IPC: sockets, files, a database, a message broker, or memory-mapped files (FileChannel.map) if you need speed on one host. The isolation is the point: one JVM hitting OutOfMemoryError can't corrupt the other.

Question 2. What does it print?Warm-up

What's the difference between calling start() and run() on a Thread? What does this print?

Tests start vs run, IllegalThreadStateException

Show answerHide answer2 follow-ups

Model answer

public class StartVsRun {
    public static void main(String[] args) throws InterruptedException {
        Runnable task = () -> System.out.println("running in " + Thread.currentThread().getName());
        Thread t = new Thread(task, "worker");
        t.run();
        t.start();
        t.join();
        t.start();
    }
}

Real output on Java 21 (java StartVsRun.java):

running in main
running in worker
Exception in thread "main" java.lang.IllegalThreadStateException
	at java.base/java.lang.Thread.start(Thread.java:1525)
	at StartVsRun.main(StartVsRun.java:8)

Notice three things:

  • run() is a plain method call. No new thread is created; the task runs on main, synchronously.
  • start() asks the JVM to create a new OS thread, which then calls run() on its own stack. start() returns right away.
  • A thread can be started at most once, even after it has terminated. The second start() throws IllegalThreadStateException (an unchecked exception). If you need to run the task again, create a new Thread or, better, submit the Runnable to an executor.

How I’d say it in the interview

"run is a normal method call on the current thread, so nothing is concurrent. start is what creates the new thread, and the new thread calls run. And a Thread object is single-use: calling start a second time throws IllegalThreadStateException, even after the first run finished."

Signals depth

Knowing the restart rule holds after termination too, and that the fix is "new Thread or an executor", not "reset the thread". Mentioning that start() makes the new thread see everything the starting thread did before the call (a happens-before edge, JLS §17.4.5).

Red flags

"Both start the thread, run just doesn't return a value." Or claiming a finished thread can be restarted.

Follow-ups interviewers ask next

  1. What if you call start() and then immediately print t.getState()?

    You'll usually see RUNNABLE, but TERMINATED is possible if the task was tiny and already finished. You never see NEW after start() returns. The exact state is a race, which is why tests that assert on it are flaky.

  2. What if the Thread is a virtual thread and you call run() directly?

    The Java 21 Javadoc says calling run() directly on a virtual thread does nothing. On a platform thread created with a Runnable, it runs the task on the caller. One more reason never to call run() yourself.

Question 3. ScenarioWarm-up

You have 20 runnable threads and a 2-core machine. How many run at the same time, and is that concurrency or parallelism?

Tests concurrency vs parallelism, time slicing, context switches

Model answer, how to say it, 1 follow-up: unlock with the Java Pass

Question 4. ConceptWarm-up

How many ways can you create a thread in Java? When would you extend Thread versus implement Runnable?

Tests Thread, Runnable, Callable, FutureTask, executors

Model answer, how to say it, 1 follow-up: unlock with the Java Pass

Question 5. ConceptCore

How do you create a virtual thread in Java 21?

Tests Thread.Builder, virtual threads, JEP 444

Model answer, how to say it, 1 follow-up: unlock with the Java Pass

Question 6. ConceptCore

A worker thread throws a RuntimeException. What happens to that thread, to main, and to the JVM?

Tests uncaught exceptions, UncaughtExceptionHandler, thread isolation

Model answer, how to say it, 1 follow-up: unlock with the Java Pass

Question 7. DebuggingCore

Your team submits tasks to an ExecutorService. Some fail, but nothing shows up in the logs. What's going on?

Tests submit vs execute, FutureTask, ExecutionException

Model answer, how to say it, 1 follow-up: unlock with the Java Pass

Question 8. ConceptCore

Name the thread states in Java. What's the difference between BLOCKED and WAITING?

Tests Thread.State, monitors, parking

Model answer, how to say it, 3 follow-ups: unlock with the Java Pass

Question 9. ConceptCore

What's the difference between wait() and sleep()? What happens to the locks you hold?

Tests wait vs sleep, monitor release

Model answer, how to say it, 1 follow-up: unlock with the Java Pass

Question 10. What does it print?Core

What does join() do? And what happens if a thread calls Thread.currentThread().join()?

Tests join, happens-before, self-deadlock

Model answer, how to say it, 1 follow-up: unlock with the Java Pass

Question 11. What does it print?Core

What is a daemon thread? What does this program print?

Tests daemon threads, JVM shutdown, finally

Model answer, how to say it, 2 follow-ups: unlock with the Java Pass

Question 12. DebuggingCore

Your program prints all its results but never exits. A thread dump shows pool-1-thread-1 and pool-1-thread-2 in WAITING. What's wrong?

Tests non-daemon executor threads, shutdown, ExecutorService.close

Model answer, how to say it, 1 follow-up: unlock with the Java Pass

Question 13. ScenarioSenior

You call CompletableFuture.runAsync(() -> sendEmail()) at the end of main. The email sometimes never goes out. Why?

Tests common pool, daemon threads, fire-and-forget

Model answer, how to say it, 1 follow-up: unlock with the Java Pass

Question 14. ConceptCore

If I set one thread to MAX_PRIORITY and another to MIN_PRIORITY, does the high-priority one run first?

Tests thread priorities, OS scheduling

Model answer, how to say it, 1 follow-up: unlock with the Java Pass

Question 15. ConceptCore

How do you stop a thread in Java? Why is Thread.stop() off the table?

Tests cooperative cancellation, Thread.stop, interrupts

Model answer, how to say it, 1 follow-up: unlock with the Java Pass

Question 16. What does it print?Core

What's the difference between Thread.interrupted() and isInterrupted()? What does this print?

Tests interrupt flag, clearing semantics

Model answer, how to say it, 1 follow-up: unlock with the Java Pass

Question 17. DebuggingCore

What's wrong with this code: catch (InterruptedException e) {}?

Tests interrupt handling, propagate or restore

Model answer, how to say it, 1 follow-up: unlock with the Java Pass

Question 18. ScenarioSenior

You call interrupt() on a thread but it never stops. What could be going on?

Tests non-interruptible blocking, synchronized, socket I/O, lockInterruptibly

Model answer, how to say it, 1 follow-up: unlock with the Java Pass

Question 19. ConceptSenior

What does Future.cancel(true) actually do? And how is shutdown() different from shutdownNow()?

Tests Future.cancel, ExecutorService shutdown, interrupts

Model answer, how to say it, 1 follow-up: unlock with the Java Pass

Question 20. CodingSenior

Write a worker that processes jobs from a queue until it's told to stop. It must stop promptly, even while it's waiting for work.

Tests cancellable loop, interrupt handling, cleanup

Model answer, how to say it, 2 follow-ups: unlock with the Java Pass

Premium question set

Keep reading with the Java Pass

The rest of this question set is part of Java One-Stop Interview Prep: in-depth explanations, diagrams, model answers and how to say them in the interview.

From ₹299 · one-time payment · No auto-renewal

Lessons in Thread basics