FileDocCategorySizeDatePackage
RWLock.javaAPI DocGlassfish v2 API7619Fri May 04 22:32:20 BST 2007com.sun.enterprise.util.sync

RWLock

public class RWLock extends Object
A RWLock provides concurrency control for multiple readers single writer access patterns. This lock can provide access to multiple reader threads simultaneously as long as there are no writer threads. Once a writer thread gains access to the instance locked by a RWLock, all the reader threads wait till the writer completes accessing the instance in question.

A RWLock is extremely useful in scenarios where there are lots more readers and very few writers to a data structure. Also if the read operation by the reader thread could take significant amount of time (binary search etc.)

The usage of Lock can be see as under:


public class MyBTree {
private RWLock lock = new Lock();
.....
.....
public Object find(Object o) {
try {
lock.acquireReadLock();
....perform complex search to get the Object ...
return result;
} finally {
lock.releaseReadLock();
}
}

public void insert(Object o) {
try {
lock.acquireWriteLock();
....perform complex operation to insert object ...
} finally {
lock.releaseWriteLock();
}
}
}

author
Dhiru Pandey 8/7/2000

Fields Summary
static Logger
_logger
int
currentReaders
int
pendingReaders
int
currentWriters
Queue
writerQueue
Constructors Summary
Methods Summary
public synchronized voidacquireReadLock()
This method is used to acquire a read lock. If there is already a writer thread accessing the object using the RWLock then the reader thread will wait until the writer completes its operation


                                       
      
    if (currentWriters == 0 && writerQueue.size() == 0) {
      ++currentReaders;
    } else {
      ++pendingReaders;
      try {
        wait();
      } catch(InterruptedException ie) {
      }
    }
  
public voidacquireWriteLock()
This method is used to acquire a write lock. If there are already reader threads accessing the object using the RWLock, then the writer thread will wait till all the reader threads are finished with their operations.

    Object lock = new Object();

    synchronized(lock) {
      synchronized(this) {
        if (writerQueue.size() == 0 && currentReaders == 0 && 
                                          currentWriters == 0) {
          ++currentWriters;
          // Use logging facility if you need to log this
//          System.out.println(" RW: incremented WriterLock count");
//Bug 4677074 begin
            _logger.log(Level.FINE," RW: incremented WriterLock count");
//Bug 4677074 end
          return;
        }
          writerQueue.enQueue(lock);
          // Use logging facility if you need to log this
//          System.out.println(" RW: Added WriterLock to queue");
//Bug 4677074 begin
            _logger.log(Level.FINE," RW: Added WriterLock to queue");
//Bug 4677074 end
      }
      try {
        lock.wait();
      } catch(InterruptedException ie) {
      }
    }
  
private voidnotifyReaders()

    currentReaders += pendingReaders;
    pendingReaders = 0;
    notifyAll();
  
private voidnotifyWriters()

    if (writerQueue.size() > 0) {
      Object lock = writerQueue.deQueueFirst();
      ++currentWriters;
      synchronized(lock) { 
        lock.notify();
      }
    }
  
public synchronized voidreleaseReadLock()
This method is used to release a read lock. It also notifies any waiting writer thread that it could now acquire a write lock.

    if (--currentReaders == 0) 
      notifyWriters();
  
public synchronized voidreleaseWriteLock()
This method is used to release a write lock. It also notifies any pending readers that they could now acquire the read lock. If there are no reader threads then it will try to notify any waiting writer thread that it could now acquire a write lock.

    --currentWriters;
    if (pendingReaders > 0) 
      notifyReaders();
    else 
      notifyWriters();