0% found this document useful (0 votes)
12 views3 pages

Section 5 Java Multithreading True Senior H1 H2

The document discusses various aspects of Java multithreading, including detecting and fixing deadlocks, the benefits of ReentrantLock over synchronized blocks, and debugging race conditions. It also covers the role of ForkJoinPool, the impact of the Java Memory Model on variable visibility, and the use of CountDownLatch versus CyclicBarrier. Additionally, it addresses designing thread-safe caches, limitations of synchronized, task rejection handling in ExecutorService, and implementing cooperative cancellation for long-running tasks.

Uploaded by

pbecic
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views3 pages

Section 5 Java Multithreading True Senior H1 H2

The document discusses various aspects of Java multithreading, including detecting and fixing deadlocks, the benefits of ReentrantLock over synchronized blocks, and debugging race conditions. It also covers the role of ForkJoinPool, the impact of the Java Memory Model on variable visibility, and the use of CountDownLatch versus CyclicBarrier. Additionally, it addresses designing thread-safe caches, limitations of synchronized, task rejection handling in ExecutorService, and implementing cooperative cancellation for long-running tasks.

Uploaded by

pbecic
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 3

5.

Java Multithreading

How would you detect and fix a deadlock in a production Java application?
 Use thread dumps and tools like VisualVM or jstack to identify threads blocked on
monitors.
 Analyze lock acquisition order and look for cyclic dependencies between thread stacks.
 Refactor code to acquire locks in a consistent global order across threads.
 Introduce lock timeouts or use java.util.concurrent locks with tryLock to avoid
indefinite blocking.
 Monitor lock contention and usage metrics continuously in production to catch
regressions early.

What are the benefits and trade-offs of using ReentrantLock over synchronized
blocks?
 ReentrantLock offers finer-grained control, supports tryLock(), and timed lock
acquisition.
 Supports fair locking policy and condition variables for advanced wait/notify scenarios.
 More verbose than synchronized and easier to misuse (must manually unlock in all
paths).
 Allows interruptible lock acquisition, which is useful in cancellation scenarios.
 Preferred when advanced coordination or lock polling is required.

How would you debug a race condition that happens intermittently under load?
 Use stress testing tools (e.g., jcstress) and randomized inputs to increase failure
likelihood.
 Inject artificial delays or reorderings to simulate timing issues in multithreaded paths.
 Capture shared state access and modification patterns using logging or trace probes.
 Apply volatile or synchronized to enforce memory visibility when needed.
 Reproduce issue in isolation and narrow down minimal failing scenario for root cause
analysis.

What is the role of the ForkJoinPool and how is it different from a fixed thread
pool?
 ForkJoinPool is designed for work-stealing, ideal for recursive and parallel divide-and-
conquer tasks.
 Threads in ForkJoinPool can 'steal' tasks from other queues, improving load balancing.
 Fixed thread pools use a shared queue and are better for uniform task workloads.
 ForkJoinPool supports fine-grained parallelism with reduced context switching
overhead.
 Misuse (e.g., blocking calls inside tasks) can starve worker threads and cause deadlocks.
How does the Java Memory Model impact the visibility of shared variables
between threads?
 Without synchronization, threads may cache variables and see stale or inconsistent
values.
 Volatile fields ensure visibility but not atomicity; writes are immediately visible to other
threads.
 Synchronized blocks establish happens-before relationships that flush thread-local
caches.
 Final fields in constructors are guaranteed to be visible if safely published.
 Understanding JMM is essential for writing safe lock-free and concurrent code.

When would you use a CountDownLatch vs a CyclicBarrier?


 CountDownLatch is used for one-time event coordination (e.g., waiting for N threads to
complete).
 CyclicBarrier allows threads to wait for each other at a common barrier point and is
reusable.
 CountDownLatch is not resettable; CyclicBarrier can be reused across phases.
 Use CyclicBarrier when threads must wait and proceed together in phases (e.g.,
simulation steps).
 Both require careful exception handling to avoid broken synchronization state.

How would you design a thread-safe cache for concurrent reads and writes?
 Use ConcurrentHashMap for segment-based concurrent access without full locking.
 Add expiration with Caffeine or Guava for bounded size and eviction policies.
 Use computeIfAbsent for atomic loading behavior without double-checked locking.
 Avoid holding locks during expensive computations or I/O operations.
 Design read/write patterns to minimize contention and false sharing.

What are the limitations of using synchronized in highly concurrent


applications?
 Leads to thread blocking and increased context switching under high contention.
 No support for fairness, timeouts, or interruption during lock acquisition.
 Can degrade scalability and throughput when lock granularity is coarse.
 Harder to reason about nested monitor locks and reentrancy across class hierarchies.
 Advanced concurrency utilities offer more flexible and scalable alternatives.

How does the ExecutorService handle task rejection and what strategies exist
to manage it?
 ExecutorService uses a bounded queue and RejectExecutionHandler when it cannot
accept tasks.
 Default behavior (AbortPolicy) throws RejectedExecutionException if the queue is full.
 Custom policies can log, retry, discard, or run tasks on the caller thread.
 Tune core/max threads and queue size based on workload patterns and latency SLAs.
 Backpressure and metrics should be monitored to prevent silent task loss or overload.

How would you implement cooperative cancellation for long-running tasks?


 Use an atomic boolean or thread interruption to signal cancellation intent.
 Check the cancel flag or Thread.interrupted() periodically inside the task body.
 Ensure resources (e.g., I/O, database connections) are released promptly on cancel.
 Design loop-based tasks to be cancellable at defined safe checkpoints.
 Avoid swallowing InterruptedException and propagate or handle it appropriately.

You might also like