๐ Java Concurrency Primitives: Locks, AtomicLong, LongAdder, and More
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, fair locks, or interruptible waits.
3. ๐งช AtomicLong
For simple counters without locking, use AtomicLong
or AtomicInteger
.
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
is better than AtomicLong because it splits the counter into cells to reduce contention.
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:
allows multiple readers, single writer for shared data.StampedLock:
supports optimistic reads for very high-performance cases.ConcurrentHashMap:
discussed in our previous post — atomic operations per key.Semaphore:
limits concurrent access to a resource pool.
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, contention levels, and performance requirements.
Labels: Java, Concurrency, Locks, AtomicLong, LongAdder, ReentrantLock, Multithreading, Performance, Thread Safety
Comments
Post a Comment