1 33 34 package edu.rice.cs.util; 35 36 import edu.rice.cs.drjava.DrJavaTestCase; 37 38 44 public class ReaderWriterLockTest extends DrJavaTestCase { 45 46 protected ReaderWriterLock _lock; 47 48 49 public void setUp() throws Exception { 50 super.setUp(); 51 _lock = new ReaderWriterLock(); 52 } 53 54 56 57 private int _notifyCount = 0; 58 59 60 private final Object _notifyObject = new Object (); 61 62 63 private void _notify() { 64 synchronized(_notifyObject) { 65 _notifyCount--; 66 if (_notifyCount <= 0) { 67 _notifyObject.notify(); 68 _notifyCount = 0; 69 } 70 } 71 } 72 73 75 public void testMultipleReaders() throws InterruptedException { 76 final StringBuilder buf = new StringBuilder (); 77 78 ReaderThread r1 = new PrinterReaderThread("r1 ", buf); 80 ReaderThread r2 = new PrinterReaderThread("r2 ", buf); 81 ReaderThread r3 = new PrinterReaderThread("r3 ", buf); 82 83 _notifyCount = 3; 85 86 synchronized(_notifyObject) { 88 r1.start(); 89 r2.start(); 90 r3.start(); 91 _notifyObject.wait(); 92 } 93 } 96 97 98 public void testMultipleWriters() throws InterruptedException { 99 final StringBuilder buf = new StringBuilder (); 100 101 WriterThread w1 = new PrinterWriterThread("w1 ", buf); 103 WriterThread w2 = new PrinterWriterThread("w2 ", buf); 104 WriterThread w3 = new PrinterWriterThread("w3 ", buf); 105 106 _notifyCount = 3; 108 109 synchronized(_notifyObject) { 111 w1.start(); 112 w2.start(); 113 w3.start(); 114 _notifyObject.wait(); 115 } 116 String output = buf.toString(); 117 119 assertTrue("w1 writes should happen in order", output.indexOf("w1 w1 w1 ") != -1); 121 assertTrue("w2 writes should happen in order", output.indexOf("w2 w2 w2 ") != -1); 122 assertTrue("w1 writes should happen in order", output.indexOf("w3 w3 w3 ") != -1); 123 } 124 125 126 public void testReaderMultipleReads() throws InterruptedException { 127 _lock.startRead(); 129 _lock.startRead(); 130 _lock.endRead(); 131 _lock.endRead(); 132 133 _lock.startRead(); 136 Thread w = new Thread () { 137 public void run() { 138 synchronized(_lock) { 139 _lock.notifyAll(); 140 _lock.startWrite(); 141 _lock.endWrite(); 143 } 144 } 145 }; 146 synchronized(_lock) { 147 w.start(); 148 _lock.wait(); 149 } 150 _lock.startRead(); 151 _lock.endRead(); 152 _lock.endRead(); 153 } 154 155 156 public void testCannotWriteInARead() { 157 try { 158 _lock.startRead(); 159 _lock.startWrite(); 160 fail("Should have caused an IllegalStateException!"); 161 } 162 catch (IllegalStateException ise) { 163 } 165 } 166 167 168 public void testCannotWriteInAWrite() { 169 try { 170 _lock.startWrite(); 171 _lock.startWrite(); 172 fail("Should have caused an IllegalStateException!"); 173 } 174 catch (IllegalStateException ise) { 175 } 177 } 178 179 180 public void testCannotReadInAWrite() { 181 try { 182 _lock.startWrite(); 183 _lock.startRead(); 184 fail("Should have caused an IllegalStateException!"); 185 } 186 catch (IllegalStateException ise) { 187 } 189 } 190 191 192 217 public void testMultipleReadersAndWriters() throws InterruptedException { 218 final StringBuilder buf = new StringBuilder (); 219 220 WriterThread w1 = new PrinterWriterThread("w1 ", buf); 222 WriterThread w2 = new PrinterWriterThread("w2 ", buf); 223 WriterThread w3 = new PrinterWriterThread("w3 ", buf); 224 225 ReaderThread r1 = new PrinterReaderThread("r1 ", buf); 226 ReaderThread r2 = new PrinterReaderThread("r2 ", buf); 227 ReaderThread r3 = new PrinterReaderThread("r3 ", buf); 228 ReaderThread r4 = new PrinterReaderThread("r4 ", buf); 229 ReaderThread r5 = new PrinterReaderThread("r5 ", buf); 230 231 _notifyCount = 8; 233 234 synchronized(_notifyObject) { 236 w1.start(); 237 w2.start(); 238 r1.start(); 239 r2.start(); 240 w3.start(); 241 r3.start(); 242 r4.start(); 243 r5.start(); 244 _notifyObject.wait(); 245 } 246 String output = buf.toString(); 247 249 assertTrue("w1 writes should happen in order", output.indexOf("w1 w1 w1 ") != -1); 251 assertTrue("w2 writes should happen in order", output.indexOf("w2 w2 w2 ") != -1); 252 assertTrue("w1 writes should happen in order", output.indexOf("w3 w3 w3 ") != -1); 253 } 254 255 256 257 public abstract class ReaderThread extends Thread { 258 public abstract void read() throws Throwable ; 259 public void run() { 260 _lock.startRead(); 261 try { read(); } 262 catch (Throwable t) { t.printStackTrace(); } 263 _lock.endRead(); 264 } 265 } 266 267 268 public abstract class WriterThread extends Thread { 269 public abstract void write() throws Throwable ; 270 public void run() { 271 _lock.startWrite(); 272 try { write(); } 273 catch (Throwable t) { t.printStackTrace(); } 274 _lock.endWrite(); 275 } 276 } 277 278 279 public class PrinterReaderThread extends ReaderThread { 280 PrintCommand _command; 281 public PrinterReaderThread(String msg, final StringBuilder buf) { _command = new PrintCommand(msg, buf); } 282 public void read() { _command.print(); } 283 } 284 285 286 public class PrinterWriterThread extends WriterThread { 287 PrintCommand _command; 288 public PrinterWriterThread(String msg, final StringBuilder buf) { _command = new PrintCommand(msg, buf); } 289 public void write() { _command.print(); } 290 } 291 292 293 public class PrintCommand { 294 295 int _numIterations = 3; 296 297 int _waitMillis = 5; 298 299 final StringBuilder _buf; 300 301 final String _msg; 302 303 public PrintCommand(String msg, StringBuilder buf) { 304 _msg = msg; 305 _buf = buf; 306 } 307 308 public void print() { 309 for (int i=0; i < _numIterations; i++) { 310 _buf.append(_msg); 311 try { Thread.sleep(_waitMillis); } 312 catch (InterruptedException e) { _buf.append(e); } 313 } 314 _notify(); 315 } 316 } 317 } 318 | Popular Tags |