Class SimpleReadWriteLock

java.lang.Object
java.util.concurrent.locks.ReentrantReadWriteLock
org.apache.juneau.commons.concurrent.SimpleReadWriteLock
All Implemented Interfaces:
Serializable, ReadWriteLock

An extension of ReentrantReadWriteLock with convenience methods for creating auto-closeable locks that work seamlessly with try-with-resources statements.

This class provides a simpler API than the standard ReentrantReadWriteLock by wrapping read and write locks in SimpleLock instances that implement AutoCloseable. This allows locks to be automatically released when used in try-with-resources blocks, reducing the risk of forgetting to unlock and preventing deadlocks.

The returned SimpleLock instances automatically acquire the lock when created and release it when SimpleLock.close() is called (either explicitly or automatically via try-with-resources).

Example:

// Using read lock with try-with-resources var lock = new SimpleReadWriteLock(); try (var readLock = lock.read()) { // Read operations here - lock is automatically held sharedResource.read(); } // Lock is automatically released when exiting try block // Using write lock with try-with-resources try (var writeLock = lock.write()) { // Write operations here - lock is automatically held sharedResource.write("new value"); } // Lock is automatically released when exiting try block

Thread Safety:

This class inherits all thread-safety guarantees from ReentrantReadWriteLock. Multiple threads can hold read locks simultaneously, but write locks are exclusive. Read and write locks cannot be held simultaneously by different threads.

Notes:
  • The returned SimpleLock instances are not thread-safe themselves and should not be shared between threads. Each thread should call read() or write() separately.
  • Each call to read() or write() returns a new SimpleLock instance.
  • The lock is automatically acquired when SimpleLock is created and released when SimpleLock.close() is called.
  • This class supports reentrant locking - the same thread can acquire multiple read locks or upgrade from read to write lock (if no other threads hold read locks).
  • For fair ordering, use SimpleReadWriteLock(boolean) with true.
See Also:
See Also:
  • Field Details

    • NO_OP

      public static final SimpleReadWriteLock NO_OP
      A no-op lock instance that performs no actual locking operations.

      This instance can be used when locking is conditionally disabled or when you need a SimpleReadWriteLock instance but don't want any actual synchronization overhead. All lock operations on this instance are no-ops and return SimpleLock.NO_OP.

      Example:

      // Use NO_OP when locking is disabled var lock = isLockingEnabled() ? new SimpleReadWriteLock() : SimpleReadWriteLock.NO_OP; try (var readLock = lock.read()) { // Code works the same whether locking is enabled or not sharedResource.read(); }

      Notes:
  • Constructor Details

    • SimpleReadWriteLock

      Constructor.

      Creates a new read-write lock with an unfair ordering policy. Unfair locks generally provide better throughput under high contention but may not guarantee fairness.

    • SimpleReadWriteLock

      public SimpleReadWriteLock(boolean fair)
      Constructor.

      Creates a new read-write lock with the specified fairness policy.

      Fair vs Unfair:
      • Fair locks (true): Threads acquire locks in approximately FIFO order. Provides fairness but may have lower throughput under high contention.
      • Unfair locks (false): No ordering guarantee. Generally provides better throughput but may starve some threads under high contention.
      Parameters:
      fair - true if this lock should use a fair ordering policy, false for unfair.
  • Method Details

    • read

      public SimpleLock read()
      Acquires and returns a read lock.

      The returned SimpleLock automatically acquires the read lock when created and releases it when SimpleLock.close() is called. Multiple threads can hold read locks simultaneously, but a write lock cannot be acquired while any read locks are held.

      Example:

      var lock = new SimpleReadWriteLock(); try (var readLock = lock.read()) { // Multiple threads can hold read locks simultaneously sharedResource.read(); } // Lock is automatically released

      Notes:
      • This method blocks until the read lock can be acquired.
      • Multiple threads can hold read locks concurrently.
      • Read locks cannot be acquired while a write lock is held by another thread.
      • The same thread can acquire multiple read locks (reentrant).
      • Each call returns a new SimpleLock instance.
      Returns:
      A new SimpleLock that holds the read lock. The lock is automatically acquired.
    • write

      public SimpleLock write()
      Acquires and returns a write lock.

      The returned SimpleLock automatically acquires the write lock when created and releases it when SimpleLock.close() is called. Write locks are exclusive - only one thread can hold a write lock at a time, and no read locks can be held while a write lock is active.

      Example:

      var lock = new SimpleReadWriteLock(); try (var writeLock = lock.write()) { // Only one thread can hold a write lock at a time sharedResource.write("new value"); } // Lock is automatically released

      Notes:
      • This method blocks until the write lock can be acquired.
      • Write locks are exclusive - only one thread can hold a write lock at a time.
      • Write locks cannot be acquired while any read locks are held by other threads.
      • Read locks cannot be acquired while a write lock is held.
      • The same thread can acquire multiple write locks (reentrant).
      • Each call returns a new SimpleLock instance.
      Returns:
      A new SimpleLock that holds the write lock. The lock is automatically acquired.