1
2
3
4
5
6
7 package gov.bnl.gums;
8
9 import org.apache.commons.logging.Log;
10 import org.apache.commons.logging.LogFactory;
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
22 */
23 public class ReadWriteLock {
24 private Log log = LogFactory.getLog(ReadWriteLock.class);
25
26 private int[] lock = new int[2];
27 private String name;
28
29 public ReadWriteLock(String name) {
30 this.name = name;
31 }
32
33 /*** Checks whether anybody has a read lock.
34 */
35 public synchronized boolean isReadLocked() {
36 return lock[1] != 0;
37 }
38
39 /*** Checks whether anybody is reading data.
40 */
41 public synchronized boolean isWriteLocked() {
42 return lock[0] != 0;
43 }
44
45 public synchronized void obtainWriteLock() {
46 log.trace("Trying to write on " + name + ": " + lock[0] + ", " + lock[1]);
47
48
49 while (lock[1] != 0) {
50 try {
51 log.trace("Waiting write on " + name + ": " + lock[0] + ", " + lock[1]);
52 wait();
53 } catch (InterruptedException e) {
54 log.error("Wait was interrupted: " + e.getMessage(), e);
55 }
56 }
57 lock[1] = 1;
58 log.trace("Locked write on " + name + ": " + lock[0] + ", " + lock[1]);
59 notifyAll();
60
61
62 while (lock[0] != 0) {
63 try {
64 wait();
65 } catch (InterruptedException e) {
66 log.error("Wait was interrupted: " + e.getMessage(), e);
67 }
68 }
69 }
70
71 public synchronized void releaseWriteLock() {
72 log.trace("Unlocking write on " + name + ": " + lock[0] + ", " + lock[1]);
73 lock[1]=0;
74 log.trace("Unocked write on " + name + ": " + lock[0] + ", " + lock[1]);
75 notifyAll();
76 }
77
78 public synchronized void obtainReadLock() {
79 log.trace("Trying to read on " + name + ": " + lock[0] + ", " + lock[1]);
80
81 while (lock[1] != 0) {
82 try {
83 log.trace("Waiting read on " + name + ": " + lock[0] + ", " + lock[1]);
84 wait();
85 } catch (InterruptedException e) {
86 log.error("Wait was interrupted: " + e.getMessage(), e);
87 }
88 }
89
90
91 lock[0]++;
92 log.trace("Locked read on " + name + ": " + lock[0] + ", " + lock[1]);
93 notifyAll();
94 }
95
96 public synchronized void releaseReadLock() {
97 log.trace("Unlocking read on " + name + ": " + lock[0] + ", " + lock[1]);
98 lock[0]--;
99 log.trace("Unocked read on " + name + ": " + lock[0] + ", " + lock[1]);
100 notifyAll();
101 }
102
103 }