Java Multithreading Interview Questions & Answers
Technical Overview & Core Questions
Q1. What is the fundamental difference between Process-based Multitasking and Thread-based Multithreading?
Process-based Multitasking executes independent application processes concurrently, where each process owns an isolated virtual address space (Heap, Stack, File Descriptors). Inter-Process Communication (IPC) requires heavy kernel mediation (sockets, named pipes, shared memory). Thread-based Multithreading executes light-weight concurrent execution units within a single process. All threads share the parent process's Heap memory and Metaspace, retaining only private thread-local Stacks and Program Counter (PC) registers. Thread switching is significantly faster as it avoids TLB (Translation Lookaside Buffer) flushes.
Q2. Why is multithreading preferred over process-based multitasking for internal application concurrency?
- Lower Creation Overhead: Allocating a Java thread costs of stack memory versus copying full process page directory tables.
- Faster Context Switching: Context switching between threads in the same process takes (register & stack frame swaps) compared to for process context switching (which requires swapping Page Table Base Registers and invalidating TLB entries).
- Direct Memory Sharing: Threads communicate natively by passing object references in shared Heap RAM without serialization overhead.
Q3. What is the Java "Main Thread" and how does the JVM manage its initialization and shutdown?
The Main Thread is the initial user thread spawned by the JVM native launcher (
java.exe/java). It initializes JVM subsystems (ClassLoader, Metaspace, GC worker threads), loads the entry-point class, and executespublic static void main(String[] args). The JVM process remains active until all non-daemon user threads terminate, unlessSystem.exit()is explicitly invoked.
Q4. What is the difference between User Threads and Daemon Threads in Java?
User Threads are high-priority application threads that keep the JVM process alive. The JVM will not terminate as long as at least one user thread remains active. Daemon Threads (e.g., GC workers, Finalizer, JIT compiler threads) are background support threads. When the last user thread completes, the JVM abruptly shuts down, terminating all daemon threads immediately without waiting for their
finallyblocks to execute.
Q5. What is CPU Context Switching and what metrics should be monitored to detect thread contention?
Context switching is the hardware and OS process of storing a running thread's state (Program Counter, CPU registers, Stack Pointer) into its Thread Control Block (TCB) and loading the saved state of the next scheduled thread. Excessive context switching degrades throughput. On Linux, monitor via
vmstat 1(columncs) orpidstat -w. A high non-voluntary context switch rate (nvctxsw/s) accompanied by high system CPU usage (%sys) signals high lock contention.
Q6. What is the difference between invoking Thread.start() vs invoking Thread.run() directly?
Invoking
Thread.start()executes a native JVM call (JVM_StartThreadpthread_create), allocating a new OS kernel thread that asynchronously invokesrun()on its private call stack. Invokingrun()directly performs a standard synchronous method call in the calling thread's context without spawning a new OS thread.
Q7. Can a terminated Java thread be restarted by calling start() again?
No. Once a Java thread reaches the
TERMINATEDstate, its underlying native OS thread is destroyed. Callingstart()a second time on the sameThreadinstance throws anIllegalThreadStateException. To re-execute tasks, reuse threads via anExecutorServicethread pool.
Q8. What is the difference between Runnable and Callable in Java?
Runnable: Defines a task withvoid run(). It cannot return a result to the caller and cannot throw checked exceptions.Callable<V>: Introduced in Java 5 (java.util.concurrent), defines a task withV call() throws Exception. It returns a parameterized resultVand can throw checked exceptions. When submitted to anExecutorService, it returns aFuture<V>representing the asynchronous result.
Q9. How does Thread.join() work internally?
Thread.join()causes the current executing thread to pause (WAITINGstate) until the target thread on whichjoin()was called completes execution.
- Under the hood:
join()is implemented using awhile(isAlive()) { wait(0); }synchronized loop on the targetThreadobject instance.- JVM Termination Signal: When a native thread completes its execution, the HotSpot JVM automatically calls
notifyAll()on thatThreadobject, waking up all threads waiting on its join lock.
Q10. What is Thread Interruption and how do isInterrupted() vs Thread.interrupted() differ?
Thread interruption is a cooperative mechanism: calling
t.interrupt()sets an internal boolean interrupt status flag on threadt. Iftis currently in a sleeping/waiting state (sleep(),wait(),join()), it clears the flag and throwsInterruptedException.
t.isInterrupted()(Instance Method): Returnstrueif threadtis interrupted. Does NOT clear the interrupt status flag.Thread.interrupted()(Static Method): Checks if the current thread is interrupted AND clears the interrupt flag (resets it tofalse).
Q11. What is Deadlock and how can it be diagnosed and prevented?
Deadlock occurs when two or more threads are blocked forever, each waiting for a lock held by the other (circular dependency).
- Diagnosis: Generate a thread dump via
jcmd <pid> Thread.print,jstack <pid>, or programmatically viaManagementFactory.getThreadMXBean().findDeadlockedThreads().- Prevention Strategies:
- Strict Lock Ordering: Always acquire multiple locks in the exact same predefined global order.
- Lock Timeouts: Use
ReentrantLock.tryLock(timeout, unit)instead of intrinsicsynchronizedblocks.
Q12. How does the volatile keyword work in Java?
The
volatilemodifier ensures two main memory guarantees:
- Visibility: Writes to a
volatilevariable are immediately flushed to main memory, and subsequent reads bypass CPU L1/L2 caches to read directly from main memory.- Instruction Reordering Prevention: The compiler and CPU hardware are forbidden from reordering reads/writes across a volatile access. HotSpot achieves this by inserting CPU Memory Barriers (such as
StoreLoadfences).
- Limitation:
volatiledoes NOT guarantee atomicity for compound operations (e.g.count++requires read-modify-write, which is NOT atomic and needsAtomicIntegerorsynchronized).
Native HotSpot JVM Execution Flow
Thread.start()
โโโบ JVM_StartThread() (Native C++ Call)
โโโบ os::create_thread()
โโโบ pthread_create() (Linux/macOS Kernel API)
โโโบ Thread.run() (Executed in new OS Thread Context)
