Prev Next

Java / Java Concurrency and Multi Threading in Java 17 and Java 21 Interview questions

1. What is a thread in Java? 2. What is multithreading in Java? 3. What are the different states of a thread in Java? 4. How do you create a thread in Java? 5. What is the Runnable interface used for? 6. What is a daemon thread in Java? 7. What is thread priority in Java? 8. What is the purpose of the synchronized keyword? 9. What is the purpose of the volatile keyword? 10. What are the types of locks available in java.util.concurrent.locks? 11. Define a race condition in multithreading? 12. What is the Executor framework in Java? 13. What is a virtual thread in Java 21? 14. What is a thread pool? 15. Describe the purpose of the java.util.concurrent package? 16. How does the synchronized keyword achieve mutual exclusion internally? 17. Why should you prefer ReentrantLock over synchronized in some cases? 18. What is the difference between wait() and sleep()? 19. What is the difference between notify() and notifyAll()? 20. How does ConcurrentHashMap achieve thread safety? 21. What is the difference between ConcurrentHashMap and Hashtable? 22. Why should you use CompletableFuture instead of Future? 23. How does the ForkJoinPool execute tasks? 24. What is the difference between Runnable and Callable? 25. How do you handle thread interruption in Java? 26. What happens when a deadlock occurs in a multithreaded application? 27. When should you use CountDownLatch instead of CyclicBarrier? 28. How does compare-and-swap (CAS) work in atomic classes? 29. What is the difference between ExecutorService shutdown() and shutdownNow()? 30. How is the Java Memory Model relevant to concurrent programming? 31. How does ThreadLocal work internally? 32. What is the difference between CopyOnWriteArrayList and a synchronized ArrayList? 33. When would you choose a fixed thread pool over a cached thread pool? 34. How does a BlockingQueue support the producer-consumer pattern? 35. What happens when you call start() twice on the same thread? 36. Explain the lifecycle of a virtual thread in Java 21? 37. Explain the internal working of structured concurrency in Java 21? 38. Why does a synchronized block pin a virtual thread to its carrier thread? 39. What is the difference between ScopedValue and ThreadLocal? 40. Explain the internal working of the ForkJoinPool work-stealing algorithm? 41. How can you optimize code to avoid false sharing? 42. Why does LongAdder outperform AtomicLong under high contention? 43. Why does the ABA problem occur in lock-free CAS-based algorithms? 44. Explain the execution flow of a parallel stream operation? 45. How do you troubleshoot a deadlock in a production Java application? 46. What is the difference between StampedLock and ReadWriteLock? 47. Which is better for high-throughput I/O - platform or virtual threads, and why? 48. How can you optimize a thread pool for mixed CPU-bound and I/O-bound workloads? 49. Explain the internal working of AbstractQueuedSynchronizer (AQS)? 50. Why doesn't increasing the thread pool size always improve throughput?

1. What is a thread in Java?

A thread is the smallest independently schedulable unit of execution inside a process. Every thread has its own call stack, program counter, and local variables, but it shares the process's heap memory, open files, and static fields with every other thread in that same JVM. In Java, a thread is r...

Read full answer

2. What is multithreading in Java?

Multithreading is the ability of a Java program to run multiple threads concurrently within a single process, letting the JVM interleave or truly parallelize independent pieces of work across CPU cores. Instead of executing tasks one after another on a single thread, a multithreaded application c...

Read full answer

3. What are the different states of a thread in Java?

A Java thread moves through a well-defined set of states, represented by the Thread.State enum, over its lifetime. State Meaning NEW Thread object created but start() not yet called. RUNNABLE Executing or ready to run and waiting for CPU time from the scheduler. BLOCKED Waiting to acquire a monit...

Read full answer

4. How do you create a thread in Java?

There are three common ways to create and run a thread in Java. The first is extending Thread and overriding run() . The second, generally preferred, is implementing Runnable and passing it to a Thread constructor, which decouples the task from the threading mechanism. The third is submitting a t...

Read full answer

5. What is the Runnable interface used for?

Runnable is a functional interface with a single abstract method, void run() , that takes no arguments and returns no value. It represents a unit of work that can be executed by a thread without tying that logic to any particular execution mechanism. The same Runnable can be passed to a plain Thr...

Read full answer

6. What is a daemon thread in Java?

A daemon thread is a background thread that the JVM does not wait for when deciding whether to exit. Once every non-daemon (user) thread has finished, the JVM shuts down immediately, even if daemon threads are still running, terminating them abruptly. Common examples include the garbage collector...

Read full answer

7. What is thread priority in Java?

Thread priority is an integer hint, ranging from Thread.MIN_PRIORITY (1) to Thread.MAX_PRIORITY (10), with Thread.NORM_PRIORITY (5) as the default, that suggests to the thread scheduler how important a thread's execution is relative to others. You set it with thread.setPriority(int) and read it w...

Read full answer

8. What is the purpose of the synchronized keyword?

The synchronized keyword provides mutual exclusion: it ensures that only one thread at a time can execute a block of code or method that is guarded by the same lock, called a monitor. You can apply it to an instance method (locks on this ), a static method (locks on the class object), or an arbit...

Read full answer

9. What is the purpose of the volatile keyword?

volatile guarantees visibility: whenever a thread writes to a volatile field, that write is immediately flushed to main memory, and any thread that subsequently reads the field is guaranteed to see the latest value rather than a stale, cached copy. It also prevents the compiler and CPU from reord...

Read full answer

10. What are the types of locks available in java.util.concurrent.locks?

The java.util.concurrent.locks package offers explicit lock implementations that go beyond what the intrinsic synchronized keyword can do. Lock type Best used for ReentrantLock General-purpose mutual exclusion with tryLock, timeouts, interruptibility, and fairness options. ReentrantReadWriteLock ...

Read full answer

11. Define a race condition in multithreading?

A race condition occurs when two or more threads access shared mutable state concurrently, and the final outcome depends on the unpredictable timing or interleaving of their operations, rather than being deterministic. class Counter { int value = 0 ; void increment() { value ++ ; } // read, add 1...

Read full answer

12. What is the Executor framework in Java?

The Executor framework, in java.util.concurrent , separates task submission from the mechanics of how and when each task runs on a thread. Instead of manually creating and managing Thread objects, you submit Runnable or Callable tasks to an Executor or ExecutorService . The Executors factory clas...

Read full answer

13. What is a virtual thread in Java 21?

A virtual thread is a lightweight thread implemented and scheduled entirely by the JVM rather than mapped one-to-one to an OS thread. It was delivered as a stable feature (JEP 444) in Java 21, the result of Project Loom. Virtual threads run on top of a small pool of ordinary OS threads, called ca...

Read full answer

14. What is a thread pool?

A thread pool is a managed collection of reusable worker threads that pull tasks from a shared queue and execute them, instead of creating a brand-new thread for every task and discarding it afterward. Reusing threads avoids the relatively high cost of OS thread creation and teardown, and lets an...

Read full answer

15. Describe the purpose of the java.util.concurrent package?

java.util.concurrent is Java's standard library for building concurrent applications without hand-writing low-level wait() / notify() logic and manual locking for every scenario. It bundles several categories of tools: the Executor framework for managing thread pools and asynchronous tasks; concu...

Read full answer

16. How does the synchronized keyword achieve mutual exclusion internally?

Every Java object carries an intrinsic lock, or monitor. When a thread enters a synchronized method or block, the JVM emits a monitorenter bytecode instruction that attempts to acquire that object's monitor; a matching monitorexit releases it on normal exit or when an exception propagates out. Ho...

Read full answer

17. Why should you prefer ReentrantLock over synchronized in some cases?

ReentrantLock offers capabilities the intrinsic synchronized keyword simply doesn't have. It supports tryLock() with an optional timeout, so a thread can back off instead of blocking forever; lockInterruptibly() , so a thread waiting for the lock can respond to interruption; a configurable fairne...

Read full answer

18. What is the difference between wait() and sleep()?

wait() sleep() Defined on Object . Defined as a static method on Thread . Must be called while holding the object's monitor (inside synchronized). Can be called from anywhere, no lock required. Releases the held lock while waiting. Does not release any lock it holds. Woken by notify() / notifyAll...

Read full answer

19. What is the difference between notify() and notifyAll()?

Both methods are called on an object whose monitor the current thread holds, and both wake threads that are blocked in wait() on that same object. notify() wakes exactly one waiting thread, chosen arbitrarily by the JVM; there's no way to control or predict which one. notifyAll() wakes every thre...

Read full answer

20. How does ConcurrentHashMap achieve thread safety?

Modern ConcurrentHashMap (Java 8 onward) does not lock the entire map for every operation. Instead, it locks at the granularity of a single bin (bucket). Inserting into an empty bin is done with a lock-free compare-and-swap; if a collision lands in a bin that already has a node, only that bin's f...

Read full answer

21. What is the difference between ConcurrentHashMap and Hashtable?

ConcurrentHashMap Hashtable Locks per-bin; high concurrency for reads and writes. Synchronizes every method on a single lock for the whole map. Iterators are weakly consistent and never throw ConcurrentModificationException. The single shared lock itself becomes the concurrency bottleneck. Disall...

Read full answer

22. Why should you use CompletableFuture instead of Future?

A plain Future only lets you check whether a task is done ( isDone() ) or block until it finishes ( get() ). There's no way to attach a callback, react to completion asynchronously, or combine it with another Future . CompletableFuture , added in Java 8, implements both Future and CompletionStage...

Read full answer

23. How does the ForkJoinPool execute tasks?

ForkJoinPool is designed for divide-and-conquer workloads: a large task is recursively split into smaller subtasks until they're cheap enough to compute directly, then results are combined. You express this with RecursiveTask (returns a value) or RecursiveAction (no return value). Calling fork...

Read full answer

24. What is the difference between Runnable and Callable?

Runnable Callable Method: void run() Method: V call() throws Exception Cannot return a result. Returns a value of type V. Cannot throw checked exceptions. Can throw checked exceptions. Usable with plain Thread or an Executor. Only usable with an ExecutorService, via submit(). When you submit a...

Read full answer

25. How do you handle thread interruption in Java?

Interruption is a cooperative signal, not a forced stop. Calling thread.interrupt() sets an internal interrupt flag on that thread; it's up to the target thread's code to check for and respond to it. If the thread is currently blocked in an interruptible method like sleep() , wait() , or join() ,...

Read full answer

26. What happens when a deadlock occurs in a multithreaded application?

A deadlock happens when two or more threads each hold a lock that another thread in the group needs, and each waits forever for the other to release it, forming a circular chain that never breaks on its own. flowchart LR T1[Thread 1] -- holds --> LA[Lock A] T1 -- wants --> LB[Lock B] T2[Thread 2]...

Read full answer

27. When should you use CountDownLatch instead of CyclicBarrier?

CountDownLatch CyclicBarrier One-time use; count can only decrease and never resets. Reusable; automatically resets once the barrier trips. Some threads call countDown() while typically different threads call await(). All participating threads call await() themselves, waiting for each other. Good...

Read full answer

28. How does compare-and-swap (CAS) work in atomic classes?

CAS is a single atomic CPU instruction (like cmpxchg on x86) that takes a memory location, an expected value, and a new value. It compares the current value at that location to the expected value; if they match, it atomically writes the new value and reports success, and if they don't match, it d...

Read full answer

29. What is the difference between ExecutorService shutdown() and shutdownNow()?

shutdown() shutdownNow() Graceful: stops accepting new tasks but lets queued and running tasks finish. Aggressive: attempts to stop actively executing tasks and returns tasks that were never started. Does not interrupt running tasks. Interrupts running tasks via Thread.interrupt(). Returns void. ...

Read full answer

30. How is the Java Memory Model relevant to concurrent programming?

The Java Memory Model (JMM), formalized in JSR-133, defines the rules for when a write to a shared variable by one thread is guaranteed to be visible to a read by another thread, and what reorderings of instructions the compiler and CPU are allowed to perform. Without these rules, a compiler coul...

Read full answer

31. How does ThreadLocal work internally?

Each Thread instance internally carries its own ThreadLocalMap , a specialized hash map. Calling threadLocal.set(value) or .get() from a given thread reads or writes an entry in that specific thread's map, keyed by the ThreadLocal instance itself. private static final ThreadLocal < SimpleDateForm...

Read full answer

32. What is the difference between CopyOnWriteArrayList and a synchronized ArrayList?

CopyOnWriteArrayList Collections.synchronizedList(new ArrayList<>()) Every mutation copies the entire underlying array. Every method call is synchronized on a single shared lock. Reads never block and never throw ConcurrentModificationException. Reads acquire the same lock as writes, so they can ...

Read full answer

33. When would you choose a fixed thread pool over a cached thread pool?

A fixed thread pool ( Executors.newFixedThreadPool(n) ) keeps exactly n threads alive for its lifetime and queues excess tasks on an unbounded queue. A cached thread pool ( Executors.newCachedThreadPool() ) creates new threads as needed, reuses idle ones, and lets threads that stay idle for 60 se...

Read full answer

34. How does a BlockingQueue support the producer-consumer pattern?

A BlockingQueue adds blocking behavior on top of a normal queue: put() blocks the calling thread if the queue is full (for bounded queues), and take() blocks if the queue is empty, until an item becomes available. BlockingQueue queue = new ArrayBlockingQueue<>(100); // producer thread queue...

Read full answer

35. What happens when you call start() twice on the same thread?

Calling start() a second time on the same Thread instance, whether it's still running or already finished, throws IllegalThreadStateException . Thread t = new Thread(() -> doWork()); t.start(); t.start(); // throws IllegalThreadStateException This is because a Thread object's lifecycle is one-dir...

Read full answer

36. Explain the lifecycle of a virtual thread in Java 21?

A virtual thread's lifecycle looks like an ordinary thread's from the outside, it goes through NEW, RUNNABLE, and TERMINATED, plus WAITING/TIMED_WAITING/BLOCKED as needed, but the mechanics underneath are different. flowchart LR A[Created via Thread.ofVirtual] --> B[Scheduled onto a carrier platf...

Read full answer

37. Explain the internal working of structured concurrency in Java 21?

Structured concurrency, previewed in Java 21 via StructuredTaskScope (JEP 453), applies the idea of structured programming to concurrent tasks: a group of subtasks forked within a scope must all complete, be cancelled, or fail together, before the scope itself completes, so concurrent work gets a...

Read full answer

38. Why does a synchronized block pin a virtual thread to its carrier thread?

Normally, when a virtual thread blocks, the JVM unmounts it from its carrier and frees that carrier to run other virtual threads. Pinning is the exception: while a virtual thread is inside a synchronized block or method, or executing a native method or foreign function call, blocking there does n...

Read full answer

39. What is the difference between ScopedValue and ThreadLocal?

ThreadLocal ScopedValue (preview, Java 21+) Mutable: set() can be called any number of times. Bound once for the duration it's active, via where(...).run(...) or call(...). Value persists until explicitly removed or the thread dies. Value is only visible for the dynamic extent of the bound block,...

Read full answer

40. Explain the internal working of the ForkJoinPool work-stealing algorithm?

Each worker thread in a ForkJoinPool owns its own double-ended queue (deque) of tasks rather than pulling from one shared queue. flowchart TB W1[Worker 1 deque] -->|push/pop from head| W1 W2[Worker 2 deque] -->|push/pop from head| W2 W2 -.steal from tail.-> W1 W3[Idle Worker 3] -.steal from tail....

Read full answer

41. How can you optimize code to avoid false sharing?

False sharing happens when independent variables used by different threads happen to sit in the same CPU cache line, typically 64 bytes. Even though the threads never touch the same variable, one thread's write invalidates the entire cache line in the other thread's cache, forcing an expensive re...

Read full answer

42. Why does LongAdder outperform AtomicLong under high contention?

AtomicLong funnels every thread's update through compare-and-swap on a single shared 64-bit value. Under light contention that's cheap, but as thread count and update frequency rise, most CAS attempts fail because another thread has already changed the value, forcing repeated retries, and every t...

Read full answer

43. Why does the ABA problem occur in lock-free CAS-based algorithms?

A plain compare-and-swap only checks whether a memory location's current value still equals the expected value; it has no way to know whether that value changed and then changed back in between the read and the CAS. sequenceDiagram participant T1 as Thread 1 participant Mem as Shared value partic...

Read full answer

44. Explain the execution flow of a parallel stream operation?

Calling .parallelStream() or .stream().parallel() doesn't run your pipeline on one thread per element; it decomposes the source into chunks and submits the work to the common ForkJoinPool . flowchart TD A[Source: e.g. a List] --> B[Spliterator splits source into chunks] B --> C[Chunks recursively...

Read full answer

45. How do you troubleshoot a deadlock in a production Java application?

The first step is capturing a thread dump of the running JVM at the moment it's hung, since a deadlock leaves the involved threads permanently blocked, so the dump captures the exact stuck state. jstack # or: kill -3 and read stdout/log jcmd Thread.print jstack 's output is espe...

Read full answer

46. What is the difference between StampedLock and ReadWriteLock?

ReentrantReadWriteLock StampedLock Read lock and write lock, both truly acquired and held. Adds a third mode: optimistic read, which takes no lock at all. Reentrant: a thread can re-acquire a lock it already holds. Not reentrant; re-acquiring the same stamp-based lock from the same thread can dea...

Read full answer

47. Which is better for high-throughput I/O - platform or virtual threads, and why?

For workloads dominated by blocking I/O, such as a typical web service making blocking database or HTTP calls per request, virtual threads are the better fit in Java 21. Platform threads map one-to-one to OS threads, which are expensive to create and hold significant memory for their stacks (ofte...

Read full answer

48. How can you optimize a thread pool for mixed CPU-bound and I/O-bound workloads?

A single shared thread pool tuned for one kind of workload tends to perform badly on the other: a small pool sized for CPU-bound work leaves I/O-bound tasks queued unnecessarily since they spend most of their time waiting, not computing, while a large pool sized for I/O-bound work creates excessi...

Read full answer

49. Explain the internal working of AbstractQueuedSynchronizer (AQS)?

AbstractQueuedSynchronizer is the framework that most of java.util.concurrent 's locks and synchronizers, including ReentrantLock , Semaphore , CountDownLatch , and ReentrantReadWriteLock , are built on top of, so understanding it explains how they all share consistent, correct behavior. flowchar...

Read full answer

50. Why doesn't increasing the thread pool size always improve throughput?

Adding more threads only helps while there's a genuine resource, whether CPU cores, I/O bandwidth, or a downstream service, that those extra threads can actually put to use. Once a workload's real bottleneck is saturated, more threads just add overhead instead of more useful work. For CPU-bound w...

Read full answer

«
»

Comments & Discussions