Medium zalando java

When do ReadWriteLock and BlockingQueue help?

The 30 second answer

A read-write lock lets many readers proceed together while a writer gets exclusive access, so it helps when reads vastly outnumber writes and each read takes a while. Otherwise a plain lock is simpler and often faster. A blocking queue is the standard producer-consumer handoff: producers put, consumers take, and a bounded capacity gives you backpressure.

ReadWriteLock. ReentrantReadWriteLock holds a pair of locks: many threads may hold the read lock at once, the write lock is exclusive. It pays off for a structure read constantly and rebuilt rarely, such as an in-memory routing table or a configuration snapshot, where readers do real work under the lock. Costs and caveats from the Javadoc and practice:

  • It does not impose reader or writer preference by default; in non-fair mode a continuously contended lock can postpone some threads indefinitely. A fair mode exists at a throughput cost.
  • A thread holding the read lock cannot upgrade to the write lock; trying deadlocks. Downgrading, acquiring the read lock before releasing the write lock, is allowed.
  • If writes are frequent or critical sections tiny, the extra bookkeeping makes it slower than a single ReentrantLock.

Alternatives: an immutable snapshot swapped through a volatile or AtomicReference field gives readers no locking at all; StampedLock offers optimistic reads.

BlockingQueue. The Javadoc says implementations are designed primarily for producer-consumer queues. put blocks when a bounded queue is full and take blocks when it is empty, so a slow consumer slows producers instead of exhausting memory. offer and poll with timeouts avoid blocking forever. A BlockingQueue does not accept null, because null signals failure from poll. Choose ArrayBlockingQueue for a fixed bound, LinkedBlockingQueue with an explicit capacity, or SynchronousQueue for direct handoff.

Example use. An indexing worker that reads change events, batches them, and sends bulk requests: producers put events on a bounded queue, one or more consumers drain up to N events or wait up to T milliseconds, then send a batch. When the search cluster slows down, the queue fills and the producers slow down too.

Sources (3)
  1. ReentrantReadWriteLock Javadoc (Java 21)
  2. BlockingQueue Javadoc (Java 21)
  3. Zalando Engineering: Interview preparation tips for Java developers (June 2016)