Your browser does not support JavaScript and this site utilizes JavaScript to build content and provide links to additional information. You should either enable JavaScript in your browser settings or use a browser that supports JavaScript in order to take full advantage of this site.
1 17 18 package org.logicalcobwebs.concurrent; 19 20 34 35 public class WriterPreferenceReadWriteLock implements ReadWriteLock { 36 37 protected long activeReaders_ = 0; 38 protected Thread activeWriter_ = null; 39 protected long waitingReaders_ = 0; 40 protected long waitingWriters_ = 0; 41 42 43 protected final ReaderLock readerLock_ = new ReaderLock(); 44 protected final WriterLock writerLock_ = new WriterLock(); 45 46 public Sync writeLock() { 47 return writerLock_; 48 } 49 50 public Sync readLock() { 51 return readerLock_; 52 } 53 54 59 60 61 protected synchronized void cancelledWaitingReader() { 62 --waitingReaders_; 63 } 64 65 protected synchronized void cancelledWaitingWriter() { 66 --waitingWriters_; 67 } 68 69 70 71 protected boolean allowReader() { 72 return activeWriter_ == null && waitingWriters_ == 0; 73 } 74 75 76 protected synchronized boolean startRead() { 77 boolean allowRead = allowReader(); 78 if (allowRead) ++activeReaders_; 79 return allowRead; 80 } 81 82 protected synchronized boolean startWrite() { 83 84 87 boolean allowWrite = (activeWriter_ == null && activeReaders_ == 0); 88 if (allowWrite) activeWriter_ = Thread.currentThread(); 89 return allowWrite; 90 } 91 92 93 99 100 protected synchronized boolean startReadFromNewReader() { 101 boolean pass = startRead(); 102 if (!pass) ++waitingReaders_; 103 return pass; 104 } 105 106 protected synchronized boolean startWriteFromNewWriter() { 107 boolean pass = startWrite(); 108 if (!pass) ++waitingWriters_; 109 return pass; 110 } 111 112 protected synchronized boolean startReadFromWaitingReader() { 113 boolean pass = startRead(); 114 if (pass) --waitingReaders_; 115 return pass; 116 } 117 118 protected synchronized boolean startWriteFromWaitingWriter() { 119 boolean pass = startWrite(); 120 if (pass) --waitingWriters_; 121 return pass; 122 } 123 124 128 protected synchronized Signaller endRead() { 129 if (--activeReaders_ == 0 && waitingWriters_ > 0) 130 return writerLock_; 131 else 132 return null; 133 } 134 135 136 140 protected synchronized Signaller endWrite() { 141 activeWriter_ = null; 142 if (waitingReaders_ > 0 && allowReader()) 143 return readerLock_; 144 else if (waitingWriters_ > 0) 145 return writerLock_; 146 else 147 return null; 148 } 149 150 151 159 160 protected abstract class Signaller { abstract void signalWaiters(); 162 } 163 164 protected class ReaderLock extends Signaller implements Sync { 165 166 public void acquire() throws InterruptedException { 167 if (Thread.interrupted()) throw new InterruptedException (); 168 InterruptedException ie = null; 169 synchronized (this) { 170 if (!startReadFromNewReader()) { 171 for (; ;) { 172 try { 173 ReaderLock.this.wait(); 174 if (startReadFromWaitingReader()) 175 return; 176 } catch (InterruptedException ex) { 177 cancelledWaitingReader(); 178 ie = ex; 179 break; 180 } 181 } 182 } 183 } 184 if (ie != null) { 185 writerLock_.signalWaiters(); 189 throw ie; 190 } 191 } 192 193 194 public void release() { 195 Signaller s = endRead(); 196 if (s != null) s.signalWaiters(); 197 } 198 199 200 synchronized void signalWaiters() { 201 ReaderLock.this.notifyAll(); 202 } 203 204 public boolean attempt(long msecs) throws InterruptedException { 205 if (Thread.interrupted()) throw new InterruptedException (); 206 InterruptedException ie = null; 207 synchronized (this) { 208 if (msecs <= 0) 209 return startRead(); 210 else if (startReadFromNewReader()) 211 return true; 212 else { 213 long waitTime = msecs; 214 long start = System.currentTimeMillis(); 215 for (; ;) { 216 try { 217 ReaderLock.this.wait(waitTime); 218 } catch (InterruptedException ex) { 219 cancelledWaitingReader(); 220 ie = ex; 221 break; 222 } 223 if (startReadFromWaitingReader()) 224 return true; 225 else { 226 waitTime = msecs - (System.currentTimeMillis() - start); 227 if (waitTime <= 0) { 228 cancelledWaitingReader(); 229 break; 230 } 231 } 232 } 233 } 234 } 235 writerLock_.signalWaiters(); 237 if (ie != null) 238 throw ie; 239 else 240 return false; } 242 243 } 244 245 protected class WriterLock extends Signaller implements Sync { 246 247 public void acquire() throws InterruptedException { 248 if (Thread.interrupted()) throw new InterruptedException (); 249 InterruptedException ie = null; 250 synchronized (this) { 251 if (!startWriteFromNewWriter()) { 252 for (; ;) { 253 try { 254 WriterLock.this.wait(); 255 if (startWriteFromWaitingWriter()) 256 return; 257 } catch (InterruptedException ex) { 258 cancelledWaitingWriter(); 259 WriterLock.this.notify(); 260 ie = ex; 261 break; 262 } 263 } 264 } 265 } 266 if (ie != null) { 267 readerLock_.signalWaiters(); 271 throw ie; 272 } 273 } 274 275 public void release() { 276 Signaller s = endWrite(); 277 if (s != null) s.signalWaiters(); 278 } 279 280 synchronized void signalWaiters() { 281 WriterLock.this.notify(); 282 } 283 284 public boolean attempt(long msecs) throws InterruptedException { 285 if (Thread.interrupted()) throw new InterruptedException (); 286 InterruptedException ie = null; 287 synchronized (this) { 288 if (msecs <= 0) 289 return startWrite(); 290 else if (startWriteFromNewWriter()) 291 return true; 292 else { 293 long waitTime = msecs; 294 long start = System.currentTimeMillis(); 295 for (; ;) { 296 try { 297 WriterLock.this.wait(waitTime); 298 } catch (InterruptedException ex) { 299 cancelledWaitingWriter(); 300 WriterLock.this.notify(); 301 ie = ex; 302 break; 303 } 304 if (startWriteFromWaitingWriter()) 305 return true; 306 else { 307 waitTime = msecs - (System.currentTimeMillis() - start); 308 if (waitTime <= 0) { 309 cancelledWaitingWriter(); 310 WriterLock.this.notify(); 311 break; 312 } 313 } 314 } 315 } 316 } 317 318 readerLock_.signalWaiters(); 319 if (ie != null) 320 throw ie; 321 else 322 return false; } 324 325 } 326 327 328 } 329 330
| Popular Tags
|