Master Java Concurrency, Singleton, ThreadLocal, and Reflection for Interviews
This guide covers essential Java interview topics—including synchronized lock upgrades, object vs class locking, lazy and double‑checked singleton patterns, ThreadLocal mechanics, reflection usage, annotation scopes, Redis cluster behavior, and a linear‑time algorithm challenge—providing clear explanations, code examples, and practical insights for developers preparing for technical interviews.
Java Synchronized Lock Upgrade
Explain lock states: no lock → biased lock → lightweight lock → heavyweight lock.
No lock: default state before biased lock.
Biased lock: thread acquires lock without CAS if it already holds it.
Lightweight lock: uses CAS to acquire lock.
Heavyweight lock: when contention occurs, threads are blocked by OS.
Illustrated with image.
Object vs Class Lock
Locking an instance (synchronized(this)) only blocks threads that contend for the same object. Locking a Class object (synchronized(MyClass.class)) is a global lock for all instances of that class, protecting static variables.
Lazy Singleton and Double‑Checked Locking
Basic lazy singleton creates an instance when first requested, but is not thread‑safe. Adding synchronized to getInstance ensures safety but incurs performance cost.
Double‑checked locking reduces overhead by checking the instance twice and synchronizing only once, using a volatile instance field to prevent instruction reordering.
public class LazySingleton {
private static volatile LazySingleton instance;
private LazySingleton() {}
public static LazySingleton getInstance() {
if (instance == null) {
synchronized (LazySingleton.class) {
if (instance == null) {
instance = new LazySingleton();
}
}
}
return instance;
}
}ThreadLocal Overview
ThreadLocal provides a separate variable copy for each thread, avoiding shared mutable state. Internally each Thread holds a ThreadLocalMap where the key is the ThreadLocal object and the value is the thread‑specific data.
Typical usage:
ThreadLocal<Integer> tl = ThreadLocal.withInitial(() -> 0);
tl.set(5);
int v = tl.get();
tl.remove();Reflection Basics
Reflection allows runtime inspection and manipulation of classes, methods, fields, and constructors without compile‑time knowledge.
Typical steps: obtain Class object, locate member, invoke or access it.
Class<?> cls = Class.forName("com.example.User");
Object obj = cls.getConstructor().newInstance();
Method setName = cls.getMethod("setName", String.class);
setName.invoke(obj, "Alice");Annotation Retention Policies
SOURCE – discarded by compiler, used for source‑level checks.
CLASS – stored in bytecode, not available at runtime.
RUNTIME – retained in JVM, accessible via reflection.
Redis Cluster Concurrency
Each Redis node processes commands in a single thread, guaranteeing atomic execution per key. In cluster mode, a key is mapped to a single slot handled by one master node, so concurrent operations on the same key are serialized on that node.
Algorithm Challenge
Given an unsorted array, return the maximum difference between adjacent elements after sorting, with O(n) time and O(n) space. This can be solved using bucket sort (Pigeonhole principle).
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
IT Services Circle
Delivering cutting-edge internet insights and practical learning resources. We're a passionate and principled IT media platform.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
