Read write locks

In the great majority of database applications, the frequency of read operations greatly exceeds the frequency of write operations. This is why databases implement read-write locks for their records, which allow for concurrent reading, but still demand exclusive writing. This can markedly increase performance.

Occasionally, a class may benefit as well from a read-write lock, for exactly the same reasons - reads are much more frequent than writes. As usual, you should measure performance to determine if a read-write lock is really improving performance.

Here's a sketch of how to use such locks. It uses the ReentrantReadWriteLock of the java.util.concurrent package.

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
  User preferences, using a read-write lock. 
  
 <P>The context: preference information is read in upon startup.
 The config data is 'read-mostly': usually, a caller simply reads the 
 information. It gets updated only occasionally. 
 
 <P>Using a read-write lock means that multiple readers can access the 
 same data simultaneously. If a single writer gets the lock, however, then 
 all other callers (either reader or writer) will block until the lock is 
 released by the writer.
 
  <P>(In practice, Brian Goetz reports that the implementation of ConcurrentHashMap 
  is so good that it would likely suffice in many cases, instead of a read-write lock.)
*/
public final class Preferences {
  
  /** Fetch a setting - this is the more common operation.  */
  public String fetch(String name){
    String result = "";
    readLock.lock();
    try {
      result = preferences.get(name);
    }
    finally {
      readLock.unlock();
    }
    return result;
  }
 
  /** Change a setting - this is the less common operation. */
  public void update(String name, String value){
    writeLock.lock();
    try {
      preferences.put(name, value);
    }
    finally {
      writeLock.unlock();
    }
  }
 
  //...elided
  
  // PRIVATE
  
  /** Holds the preferences as simple name-value pairs of Strings. */
  private final Map<String, String> preferences = new LinkedHashMap<>();
  private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
  private final Lock readLock = lock.readLock();
  private final Lock writeLock = lock.writeLock();
}
 

See Also :
Use finally to unlock