๐ก️ Thread-Safe Programming in Java: Locks, Atomic Variables & LongAdder
Writing thread-safe code in Java requires understanding locks, atomic variables, and concurrent utilities. In this post, we'll explore ReentrantLock, synchronized blocks, AtomicLong, LongAdder, and when to use each.
1. ๐ Synchronized Blocks
The simplest way to make a section of code thread-safe is the synchronized keyword. It locks on an object monitor.
public class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
}
✅ Easy to use for simple critical sections
❌ Locks the entire object, can reduce concurrency
2. ๐ ReentrantLock
More flexible than synchronized blocks. Supports tryLock, timed locks, and interruptible locks.
import java.util.concurrent.locks.ReentrantLock;
ReentrantLock lock = new ReentrantLock();
lock.lock();
try {
// critical section
} finally {
lock.unlock();
}
✅ Better for advanced locking strategies, fairness, or interruptible waits
3. ๐งช AtomicLong
Use AtomicLong or AtomicInteger for simple counters without explicit locks. Operations are atomic and thread-safe.
import java.util.concurrent.atomic.AtomicLong;
AtomicLong counter = new AtomicLong();
counter.incrementAndGet();
long value = counter.get();
✅ Lock-free atomic operations, very efficient under low to moderate contention
4. ⚡ LongAdder
For high-contention counters, LongAdder splits the counter into multiple cells to reduce contention, making it faster than AtomicLong under heavy load.
import java.util.concurrent.atomic.LongAdder;
LongAdder adder = new LongAdder();
adder.increment();
long value = adder.sum();
✅ Excellent for highly concurrent counters, like metrics or request counting
5. ๐️ When to Use What
- synchronized: simple, small critical sections, low contention
- ReentrantLock: complex locking, timed/interruptible locks, fairness required
- AtomicLong: counters or values updated frequently, low contention
- LongAdder: high-throughput counters under heavy multi-threading
6. ๐ Additional Utilities
ReadWriteLock:multiple readers, single writer for shared dataStampedLock:optimistic reads for very high-performance scenariosConcurrentHashMap:atomic per-key operations, ideal for shared mapsSemaphore:limits concurrent access to a resource pool
7. ๐ Visual Summary
Simple object monitor
Advanced ReentrantLock
AtomicLong / LongAdder
8. Conclusion
Java provides a rich set of tools for thread-safe programming. Choosing the right primitive — synchronized, ReentrantLock, AtomicLong, LongAdder — depends on your concurrency needs and contention levels.
Curious about modern threading and executors? Read Modern Java Concurrency: Threads, Executors & Virtual Threads.
Labels: Java, Concurrency, Locks, AtomicLong, LongAdder, ReentrantLock, Multithreading, Performance, Thread Safety
Comments
Post a Comment