1 |
| package org.jboss.cache.lock; |
2 |
| |
3 |
| import java.util.concurrent.TimeUnit; |
4 |
| import java.util.concurrent.locks.Lock; |
5 |
| |
6 |
| import junit.framework.Test; |
7 |
| import junit.framework.TestCase; |
8 |
| import junit.framework.TestSuite; |
9 |
| import org.jboss.cache.misc.TestingUtil; |
10 |
| |
11 |
| |
12 |
| |
13 |
| |
14 |
| |
15 |
| |
16 |
| public class ReentrantWriterPreferenceReadWriteLockTest extends TestCase { |
17 |
| |
18 |
| SimpleReadWriteLock lock; |
19 |
| Lock rl, wl; |
20 |
| Exception thread_ex=null; |
21 |
| |
22 |
10
| protected void setUp() throws Exception {
|
23 |
10
| super.setUp();
|
24 |
| |
25 |
10
| lock=new SimpleReadWriteLock();
|
26 |
10
| rl=lock.readLock();
|
27 |
10
| wl=lock.writeLock();
|
28 |
10
| thread_ex=null;
|
29 |
| } |
30 |
| |
31 |
10
| protected void tearDown() throws Exception {
|
32 |
10
| super.tearDown();
|
33 |
10
| lock=null;
|
34 |
10
| if(thread_ex != null)
|
35 |
0
| throw thread_ex;
|
36 |
| } |
37 |
| |
38 |
1
| public void testMultipleReadLockAcquisitions() throws InterruptedException {
|
39 |
1
| rl.lock();
|
40 |
1
| rl.lock();
|
41 |
| } |
42 |
| |
43 |
1
| public void testInterruptedLockAcquisition() {
|
44 |
1
| Thread.currentThread().interrupt();
|
45 |
1
| try {
|
46 |
1
| rl.lockInterruptibly();
|
47 |
0
| fail("thread should be in interrupted status");
|
48 |
| } |
49 |
| catch(InterruptedException e) { |
50 |
| } |
51 |
| finally { |
52 |
1
| try {
|
53 |
1
| rl.unlock();
|
54 |
0
| fail("unlock() should throw an IllegalStateException");
|
55 |
| } |
56 |
| catch(IllegalMonitorStateException illegalStateEx) { |
57 |
1
| assertTrue(true);
|
58 |
| } |
59 |
| } |
60 |
| } |
61 |
| |
62 |
1
| public void testMultipleWriteLockAcquisitions() throws InterruptedException {
|
63 |
1
| wl.lock();
|
64 |
1
| wl.lock();
|
65 |
| } |
66 |
| |
67 |
1
| public void testMultipleReadLockReleases() throws InterruptedException {
|
68 |
1
| rl.lock();
|
69 |
1
| rl.unlock();
|
70 |
1
| try {
|
71 |
1
| rl.unlock();
|
72 |
0
| fail("we should not get here, cannot lock RL once but unlock twice");
|
73 |
| } |
74 |
| catch(IllegalMonitorStateException illegalState) { |
75 |
| |
76 |
| } |
77 |
| } |
78 |
| |
79 |
| |
80 |
0
| public void acquireReadAndWriteLocks() throws InterruptedException {
|
81 |
0
| rl.lock();
|
82 |
0
| rl.lock();
|
83 |
0
| boolean fl=wl.tryLock(4000, TimeUnit.MILLISECONDS);
|
84 |
0
| assertTrue(fl);
|
85 |
| } |
86 |
| |
87 |
| |
88 |
0
| public void acquireWriteThenReadLock() throws InterruptedException {
|
89 |
0
| wl.lock();
|
90 |
0
| rl.lock();
|
91 |
0
| wl.unlock();
|
92 |
0
| rl.unlock();
|
93 |
| } |
94 |
| |
95 |
1
| public void testMultipleWriteLockReleases() throws InterruptedException {
|
96 |
1
| wl.lock();
|
97 |
1
| wl.unlock();
|
98 |
1
| try {
|
99 |
1
| wl.unlock();
|
100 |
0
| fail("expected");
|
101 |
| } catch (IllegalMonitorStateException e) {} |
102 |
| } |
103 |
| |
104 |
1
| public void testAcquireWriteLockAfterReadLock() throws InterruptedException {
|
105 |
1
| rl.lock();
|
106 |
1
| rl.unlock();
|
107 |
1
| wl.lock();
|
108 |
| } |
109 |
| |
110 |
| |
111 |
1
| public void testAcquiringReadLockedLockWithRead() throws InterruptedException {
|
112 |
1
| new Thread() {
|
113 |
1
| public void run() {
|
114 |
1
| try {rl.lockInterruptibly();}
|
115 |
| catch(InterruptedException e) {} |
116 |
| } |
117 |
| }.start(); |
118 |
| |
119 |
1
| TestingUtil.sleepThread(500);
|
120 |
| |
121 |
| |
122 |
| |
123 |
1
| boolean flag=rl.tryLock(3000, TimeUnit.MILLISECONDS);
|
124 |
1
| assertTrue(flag);
|
125 |
1
| flag=wl.tryLock(3000, TimeUnit.MILLISECONDS);
|
126 |
1
| assertFalse(flag);
|
127 |
| } |
128 |
| |
129 |
1
| public void testAcquiringReadLockedLock() throws InterruptedException {
|
130 |
1
| new Thread() {
|
131 |
1
| public void run() {
|
132 |
1
| try {rl.lockInterruptibly();}
|
133 |
| catch(InterruptedException e) {} |
134 |
| } |
135 |
| }.start(); |
136 |
| |
137 |
1
| TestingUtil.sleepThread(500);
|
138 |
| |
139 |
| |
140 |
1
| boolean flag=wl.tryLock(3000, TimeUnit.MILLISECONDS);
|
141 |
1
| assertFalse(flag);
|
142 |
| } |
143 |
| |
144 |
1
| public void testWriteThenReadByDifferentTx() throws InterruptedException {
|
145 |
1
| Writer writer=new Writer("Writer");
|
146 |
1
| Reader reader=new Reader("Reader");
|
147 |
1
| writer.start();
|
148 |
1
| TestingUtil.sleepThread(500);
|
149 |
1
| reader.start();
|
150 |
1
| TestingUtil.sleepThread(1000);
|
151 |
| |
152 |
1
| synchronized(writer) {
|
153 |
1
| log("terminating Writer");
|
154 |
1
| writer.notify();
|
155 |
| } |
156 |
1
| TestingUtil.sleepThread(500);
|
157 |
1
| synchronized(reader) {
|
158 |
1
| reader.notify();
|
159 |
| } |
160 |
1
| writer.join();
|
161 |
1
| reader.join();
|
162 |
| } |
163 |
| |
164 |
1
| public void testReadThenWriteByDifferentTx() throws InterruptedException {
|
165 |
1
| Writer writer=new Writer("Writer");
|
166 |
1
| Reader reader=new Reader("Reader");
|
167 |
| |
168 |
1
| reader.start();
|
169 |
1
| TestingUtil.sleepThread(500);
|
170 |
1
| writer.start();
|
171 |
1
| TestingUtil.sleepThread(1000);
|
172 |
| |
173 |
1
| synchronized(reader) {
|
174 |
1
| log("terminating Reader");
|
175 |
1
| reader.notify();
|
176 |
| } |
177 |
| |
178 |
1
| TestingUtil.sleepThread(500);
|
179 |
1
| synchronized(writer) {
|
180 |
1
| writer.notify();
|
181 |
| } |
182 |
1
| writer.join();
|
183 |
1
| reader.join();
|
184 |
| } |
185 |
| |
186 |
| |
187 |
| |
188 |
18
| private static void log(String msg) {
|
189 |
18
| System.out.println(System.currentTimeMillis() + " " + Thread.currentThread() +
|
190 |
| " [" + Thread.currentThread().getName() + "]: " + msg); |
191 |
| } |
192 |
| |
193 |
| class Reader extends Thread { |
194 |
| |
195 |
2
| public Reader(String name) {
|
196 |
2
| super(name);
|
197 |
| } |
198 |
| |
199 |
2
| public void run() {
|
200 |
2
| try {
|
201 |
2
| log("acquiring RL");
|
202 |
2
| rl.lock();
|
203 |
2
| log("acquired RL");
|
204 |
2
| synchronized(this) {
|
205 |
2
| this.wait();
|
206 |
| } |
207 |
2
| log("releasing RL");
|
208 |
2
| rl.unlock();
|
209 |
2
| log("released RL");
|
210 |
| } |
211 |
| catch(InterruptedException e) { |
212 |
| ; |
213 |
| } |
214 |
| } |
215 |
| } |
216 |
| |
217 |
| |
218 |
| class Writer extends Thread { |
219 |
| |
220 |
2
| public Writer(String name) {
|
221 |
2
| super(name);
|
222 |
| } |
223 |
| |
224 |
2
| public void run() {
|
225 |
2
| try {
|
226 |
2
| log("acquiring WL");
|
227 |
2
| wl.lock();
|
228 |
2
| log("acquired WL");
|
229 |
2
| synchronized(this) {
|
230 |
2
| this.wait();
|
231 |
| } |
232 |
2
| log("releasing WL");
|
233 |
2
| wl.unlock();
|
234 |
2
| log("released WL");
|
235 |
| } |
236 |
| catch(InterruptedException e) { |
237 |
| ; |
238 |
| } |
239 |
| } |
240 |
| } |
241 |
| |
242 |
| |
243 |
| class Upgrader extends Thread { |
244 |
| boolean upgradeSuccessful=false; |
245 |
0
| public Upgrader(String name) {
|
246 |
0
| super(name);
|
247 |
| } |
248 |
| |
249 |
0
| public boolean wasUpgradeSuccessful() {
|
250 |
0
| return upgradeSuccessful;
|
251 |
| } |
252 |
| |
253 |
| |
254 |
0
| public void run() {
|
255 |
0
| try {
|
256 |
0
| log("acquiring RL");
|
257 |
0
| rl.lock();
|
258 |
0
| log("acquired RL");
|
259 |
0
| synchronized(this) {
|
260 |
0
| this.wait();
|
261 |
| } |
262 |
0
| log("attempting to lock WL");
|
263 |
| |
264 |
0
| wl.lock();
|
265 |
0
| upgradeSuccessful=true;
|
266 |
0
| log("acquired WL");
|
267 |
0
| log("releasing WL/RL");
|
268 |
0
| wl.unlock();
|
269 |
0
| log("released WL/RL");
|
270 |
| } |
271 |
| catch(InterruptedException e) { |
272 |
| ; |
273 |
| } |
274 |
| } |
275 |
| } |
276 |
| |
277 |
| |
278 |
| |
279 |
1
| public static Test suite() {
|
280 |
1
| return new TestSuite(ReentrantWriterPreferenceReadWriteLockTest.class);
|
281 |
| } |
282 |
| |
283 |
0
| public static void main(String[] args) {
|
284 |
0
| junit.textui.TestRunner.run(suite());
|
285 |
| } |
286 |
| |
287 |
| } |