Java Progressive Master Question Bank
75 progressive Java interview questions complete with technical explanations, key takeaways, diagrams, code examples, and interactive knowledge check quizzes.
Q41: What are the states in the Java Thread Lifecycle?
NEW: Thread instantiated,start()not yet called.RUNNABLE: Executing or eligible for execution in OS scheduler pool.BLOCKED: Waiting to acquire a monitor lock (synchronizedblock).WAITING: Waiting indefinitely for another thread action (Object.wait(),Thread.join()).TIMED_WAITING: Waiting for a specified time duration (Thread.sleep(ms),wait(ms)).TERMINATED: Execution completed.
BLOCKED= Waiting to acquire a monitor lock.WAITING= Waiting for thread signal notification.
Which state does a thread enter when waiting to acquire a synchronized block lock held by another thread?
Q42: What are the differences between Runnable and Callable interfaces?
Runnable:public void run(). Cannot return a result value; cannot throw checked exceptions.Callable<V>:public V call() throws Exception. Returns a generic resultV; allowed to throw checked exceptions. Used withExecutorServiceandFuture.
Runnable: Returnsvoid, handles no checked exceptions.Callable: Returns generic valueV, throws checked exceptions.
Which interface should be used for background asynchronous tasks that MUST return a calculation result?
Q43: How does the synchronized keyword work under the hood using Intrinsic Monitors?
Every Java Object possesses an Intrinsic Lock (Monitor).
- Synchronized Instance Method: Locks on
thisobject instance. - Synchronized Static Method: Locks on the class
Classobject (TargetClass.class). - Synchronized Block: Locks on a specified reference object.
Under bytecode execution,
monitorenteracquires the monitor andmonitorexitreleases it, ensuring mutual exclusion and cache flushing.
- Enforces mutual exclusion across threads accessing shared state.
- Uses bytecode
monitorenter/monitorexitdirectives on Object monitors.
What monitor object is locked when executing a synchronized static method?
Q44: What does the volatile keyword guarantee (Visibility vs Atomicity)?
volatile guarantees Memory Visibility and prevents Instruction Reordering.
- Reads and writes bypass CPU L1/L2 caches, writing directly to Main Memory.
- Establishes a Happens-Before Relationship.
- Does NOT guarantee Atomicity: Compound operations like
count++(read-modify-write) are NOT thread-safe undervolatilealone.
public class FlagWorker implements Runnable {
private volatile boolean running = true; // Visibility guaranteed across threads
public void stop() { running = false; }
@Override
public void run() {
while (running) { /* work */ }
}
}volatileguarantees main memory visibility and prevents instruction reordering.- Does NOT guarantee atomicity for compound updates (
i++). UseAtomicInteger.
Is the operation count++ thread-safe if count is declared as volatile int count?
Q45: What is a Thread Deadlock and how can it be prevented?
A Deadlock occurs when two or more threads are blocked forever, each waiting for a lock held by the other.
- 4 Coffman Conditions: Mutual Exclusion, Hold and Wait, No Preemption, Circular Wait.
- Prevention Strategies:
- Lock Ordering: Always acquire locks in a strict global sequence.
- Timed Locks: Use
ReentrantLock.tryLock(timeout)to break waiting cycles.
- Deadlocks require Circular Wait cycles across locks.
- Prevent deadlocks using consistent Lock Ordering or
tryLock(timeout).
Which strategy effectively prevents thread deadlocks in complex multi-lock systems?
Q46: How does ExecutorService manage Thread Pools, and what are the standard pool implementations?
ExecutorService decouples task submission from thread management.
FixedThreadPool: Fixed number of reusable threads backed by an unboundedLinkedBlockingQueue.CachedThreadPool: Creates new threads dynamically as needed; reclaims idle threads after 60s. Backed bySynchronousQueue.SingleThreadExecutor: Sequential single-worker execution.ScheduledThreadPool: Executes tasks periodically or after delays.
FixedThreadPooluses an unbounded task queue (risk of OOM if overwhelmed).CachedThreadPoolcreates threads dynamically (risk of high thread counts).
What memory risk is associated with default Executors.newFixedThreadPool(10) under heavy load?
Q47: How do you tune custom ThreadPoolExecutor parameters?
Constructor signature: ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler)
- Execution Flow:
- If active threads <
corePoolSize, create new thread. - If active threads $ge$
corePoolSize, queue task inworkQueue. - If
workQueueis full AND active threads <maximumPoolSize, create new thread. - If
workQueueis full AND active threads =maximumPoolSize, triggerRejectedExecutionHandler(AbortPolicy,CallerRunsPolicy).
- If active threads <
- Tasks land in
workQueueBEFORE worker count expands fromcorePoolSizetomaximumPoolSize.
When does ThreadPoolExecutor begin spawning threads beyond corePoolSize up to maximumPoolSize?
Q48: How does ReentrantLock differ from the synchronized keyword?
| Feature | synchronized | ReentrantLock |
|---|---|---|
| Lock Mechanism | Implicit JVM Monitor | Explicit Java object API |
| Fairness | Unfair lock acquisition | Supports Fair / Unfair lock configurations |
| Interruptibility | Cannot interrupt waiting thread | Supports lockInterruptibly() |
| Timed Acquisition | Not supported | Supports tryLock(timeout, unit) |
| Condition Support | Single wait-set (wait/notify) | Multiple condition variables (newCondition()) |
ReentrantLockprovides advanced features (tryLock, fairness policies, multiple conditions).
Which feature is unique to ReentrantLock compared to synchronized blocks?
Q49: How does CompletableFuture enable non-blocking asynchronous pipeline chaining?
CompletableFuture<T> implements Future<T> and CompletionStage<T>. It allows chaining asynchronous tasks without blocking thread execution:
supplyAsync(): Executes task asynchronously onForkJoinPool.commonPool().thenApply(): Transforms result synchronously ($F: A o B$).thenCompose(): Flattens nested futures ($F: A o ext{CompletableFuture}<B>$).thenCombine(): Combines two independent futures in parallel.exceptionally(): Non-blocking error recovery.
CompletableFuture.supplyAsync(() -> fetchUserData(userId))
.thenApply(user -> user.getEmail())
.thenAccept(email -> sendNotification(email))
.exceptionally(ex -> {
logger.error("Pipeline error", ex);
return null;
});- Enables functional non-blocking reactive pipelines.
thenComposeflattens nested futures;thenCombineexecutes futures in parallel.
Which CompletableFuture method is used to flatten a function that returns another CompletableFuture (similar to flatMap)?
Q50: How do Atomic variables (AtomicInteger) achieve lock-free thread safety using CAS?
Classes in java.util.concurrent.atomic (AtomicInteger, AtomicReference) provide thread-safe operations without locks using Compare-And-Swap (CAS) hardware instructions (CMPXCHG).
- CAS Loop: Reads expected value $E$, computes new value $V$. Invokes atomic CAS CPU instruction. If memory location still matches $E$, updates to $V$. If another thread modified the value, CAS fails and loops to retry.
- Lock-free thread safety using native CPU CAS instructions.
- Eliminates thread context-switching overhead under low/moderate contention.
What low-level CPU instruction enables lock-free AtomicInteger operations?