๐Ÿ”’ 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

Popular posts from this blog

๐Ÿ› ️ The Code Hut - Index

๐Ÿ“˜ Distributed Systems with Java — Series Index

๐Ÿ”„ Distributed Transactions Deep Dive