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 aName){
    String result = "";
    fReadLock.lock();
    try {
      result = fPreferences.get(aName);
    }
    finally {
      fReadLock.unlock();
    }
    return result;
  }
 
  /** Change a setting - this is the less common operation. */
  public void update(String aName, String aValue){
    fWriteLock.lock();
    try {
      fPreferences.put(aName, aValue);
    }
    finally {
      fWriteLock.unlock();
    }
  }
 
  //...elided
  
  // PRIVATE
  
  /** Holds the preferences as simple name-value pairs of Strings. */
  private final Map<String, String> fPreferences = new LinkedHashMap<>();
  private final ReentrantReadWriteLock fLock = new ReentrantReadWriteLock();
  private final Lock fReadLock = fLock.readLock();
  private final Lock fWriteLock = fLock.writeLock();
}
 



See Also :
Use finally to unlock
Would you use this technique?
Yes   No   Undecided   
© 2014 Hirondelle Systems | Source Code | Contact | License | RSS
Individual code snippets can be used under this BSD license - Last updated on September 21, 2013.
Over 2,000,000 unique IPs last year - Built with WEB4J.
- In Memoriam : Bill Dirani -