View Javadoc

1   /*
2    * ReadWriteLock.java
3    *
4    * Created on January 25, 2005, 10:39 AM
5    */
6   
7   package gov.bnl.gums.configuration;
8   
9   import org.apache.log4j.Logger;
10  
11  /** 
12   * Implements a lock to prevent access to GUMS data when updating. This is
13   * essentially the same as ReadWriteLock in JDK 1.5 (which I discovered after
14   * implementing this), which can't be used as we need JDK 1.4 compatibility.
15   * In the future it can be eliminated.
16   * <p>
17   * The write lock is exclusive, while the read locks allows for concurrent reads.
18   * Once the write lock is requested, no more reads are accepted. The write lock
19   * is guaranteed only when all read locks are released.
20   *
21   * @author Gabriele Carcassi, Jay Packard
22   */
23  public class ReadWriteLock {
24      private Logger log = Logger.getLogger(ReadWriteLock.class);
25      private int[] lock = new int[2];
26      private String name;
27      
28      public ReadWriteLock(String name) {
29          this.name = name;
30      }
31      
32      /** 
33       * Checks whether anybody has a read lock.
34       */
35      public synchronized boolean isReadLocked() {
36          return lock[1] != 0;
37      }
38      
39      /** 
40       * Checks whether anybody is reading data.
41       */
42      public synchronized boolean isWriteLocked() {
43          return lock[0] != 0;
44      }
45      
46      /**
47       * Obtain read lock.
48       */
49      public synchronized void obtainReadLock() {
50          log.trace("Trying to read on " + name + ": " + lock[0] + ", " + lock[1]);
51          // Wait that writes are finished
52          while (lock[1] != 0) {
53              try {
54                  log.trace("Waiting read on " + name + ": " + lock[0] + ", " + lock[1]);
55                  wait();
56              } catch (InterruptedException e) {
57                  log.error("Wait was interrupted: " + e.getMessage(), e);
58              }
59          }
60          
61          // Increase read counter
62          lock[0]++;
63          log.trace("Locked read on " + name + ": " + lock[0] + ", " + lock[1]);
64          notifyAll();
65      }
66      
67      /**
68       * Obtain write lock.
69       */
70      public synchronized void obtainWriteLock() {
71          log.trace("Trying to write on " + name + ": " + lock[0] + ", " + lock[1]);
72          
73          // Book a write
74          while (lock[1] != 0) {
75              try {
76                  log.trace("Waiting write on " + name + ": " + lock[0] + ", " + lock[1]);
77                  wait();
78              } catch (InterruptedException e) {
79                  log.error("Wait was interrupted: " + e.getMessage(), e);
80              }
81          }
82          lock[1] = 1;
83          log.trace("Locked write on " + name + ": " + lock[0] + ", " + lock[1]);
84          notifyAll();
85          
86          // Wait all the readers are done
87          while (lock[0] != 0) {
88              try {
89                  wait();
90              } catch (InterruptedException e) {
91                  log.error("Wait was interrupted: " + e.getMessage(), e);
92              }
93          }
94      }
95      
96      /**
97       * Release read lock.
98       */
99      public synchronized void releaseReadLock() {
100         log.trace("Unlocking read on " + name + ": " + lock[0] + ", " + lock[1]);
101         lock[0]--;
102         log.trace("Unocked read on " + name + ": " + lock[0] + ", " + lock[1]);
103         notifyAll();
104     }
105     
106     /**
107      * Release write lock.
108      */
109     public synchronized void releaseWriteLock() {
110         log.trace("Unlocking write on " + name + ": " + lock[0] + ", " + lock[1]);
111         lock[1]=0;
112         log.trace("Unocked write on " + name + ": " + lock[0] + ", " + lock[1]);
113         notifyAll();
114     }
115     
116 }