1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 package org.jage.util;
34
35 import java.util.HashMap;
36 import java.util.Map;
37
38
39
40
41
42
43
44
45
46
47
48 public class ReaderWriterLock {
49
50
51
52
53 private int readerCount = 0;
54
55
56
57
58 private final Map<Thread, Integer> readersToCounts = new HashMap<Thread, Integer>();
59
60
61
62
63 private boolean writerLock = false;
64
65
66
67
68 private int waitingReaders = 0;
69
70
71
72
73 private int waitingWriters = 0;
74
75
76
77
78 private int wakeUpReaders = 0;
79
80
81
82
83 private int wakeUpWriters = 0;
84
85
86
87
88 private final Object monitor = new Object();
89
90
91
92
93 public ReaderWriterLock() {
94
95 }
96
97
98
99
100
101
102
103 private void waitForWakingUp() throws InterruptedException {
104 while (wakeUpWriters != 0 || wakeUpReaders != 0) {
105 monitor.wait();
106 }
107 }
108
109
110
111
112
113
114 public void acquireReaderLock() throws InterruptedException {
115 synchronized (monitor) {
116 waitForWakingUp();
117
118
119
120
121
122
123 if (writerLock || (waitingWriters > 0 && !hasReaderLock(Thread.currentThread()))) {
124 waitingReaders++;
125 try {
126 do {
127 monitor.wait();
128 if (wakeUpReaders > 0) {
129 wakeUpReaders--;
130 monitor.notifyAll();
131 break;
132 }
133 } while (true);
134 } finally {
135 waitingReaders--;
136 }
137 }
138 readerCount++;
139 addReader(Thread.currentThread());
140 }
141 }
142
143 private void addReader(Thread thread) {
144 Integer count = readersToCounts.get(thread);
145 if (count == null) {
146 readersToCounts.put(thread, Integer.valueOf(1));
147 } else {
148 readersToCounts.put(thread, Integer.valueOf(count.intValue() + 1));
149 }
150 }
151
152 private void removeReader(Thread thread) {
153 Integer count = readersToCounts.get(thread);
154 readersToCounts.put(thread, Integer.valueOf(count.intValue() - 1));
155 }
156
157 private boolean hasReaderLock(Thread thread) {
158 Integer count = readersToCounts.get(thread);
159 if ((count != null) && (count.intValue() > 0)) {
160 return true;
161 }
162 return false;
163 }
164
165
166
167
168
169
170 public void releaseReaderLock() throws InterruptedException {
171 synchronized (monitor) {
172 waitForWakingUp();
173
174 readerCount--;
175 removeReader(Thread.currentThread());
176 if (readerCount == 0) {
177 if (waitingWriters >= 1) {
178 wakeUpWriters = 1;
179 monitor.notifyAll();
180 }
181 }
182 }
183 }
184
185
186
187
188
189
190 public void acquireWriterLock() throws InterruptedException {
191 synchronized (monitor) {
192 waitForWakingUp();
193
194 if (readerCount > 0 || writerLock) {
195 waitingWriters++;
196 try {
197 do {
198 monitor.wait();
199 if (wakeUpWriters == 1) {
200 wakeUpWriters = 0;
201 monitor.notifyAll();
202 break;
203 }
204 } while (true);
205 } finally {
206 waitingWriters--;
207 }
208 }
209 writerLock = true;
210 }
211 }
212
213
214
215
216
217
218 public void releaseWriterLock() throws InterruptedException {
219 synchronized (monitor) {
220 waitForWakingUp();
221
222 writerLock = false;
223 if (waitingReaders > 0) {
224 wakeUpReaders = waitingReaders;
225 monitor.notifyAll();
226 } else {
227 if (waitingWriters >= 1) {
228 wakeUpWriters = 1;
229 monitor.notifyAll();
230 }
231 }
232 }
233 }
234 }