1 17 18 package org.sape.carbon.core.util.thread; 19 20 33 34 35 53 public class WriterPreferenceReadWriteLock implements ReadWriteLock { 54 55 protected long activeReaders_ = 0; 56 protected Thread activeWriter_ = null; 57 protected long waitingReaders_ = 0; 58 protected long waitingWriters_ = 0; 59 60 61 protected final ReaderLock readerLock_ = new ReaderLock(); 62 protected final WriterLock writerLock_ = new WriterLock(); 63 64 public Sync writeLock() { return writerLock_; } 65 public Sync readLock() { return readerLock_; } 66 67 72 73 74 protected synchronized void cancelledWaitingReader() { --waitingReaders_; } 75 protected synchronized void cancelledWaitingWriter() { --waitingWriters_; } 76 77 78 79 protected boolean allowReader() { 80 return activeWriter_ == null && waitingWriters_ == 0; 81 } 82 83 84 protected synchronized boolean startRead() { 85 boolean allowRead = allowReader(); 86 if (allowRead) ++activeReaders_; 87 return allowRead; 88 } 89 90 protected synchronized boolean startWrite() { 91 92 95 boolean allowWrite = (activeWriter_ == null && activeReaders_ == 0); 96 if (allowWrite) activeWriter_ = Thread.currentThread(); 97 return allowWrite; 98 } 99 100 101 107 108 protected synchronized boolean startReadFromNewReader() { 109 boolean pass = startRead(); 110 if (!pass) ++waitingReaders_; 111 return pass; 112 } 113 114 protected synchronized boolean startWriteFromNewWriter() { 115 boolean pass = startWrite(); 116 if (!pass) ++waitingWriters_; 117 return pass; 118 } 119 120 protected synchronized boolean startReadFromWaitingReader() { 121 boolean pass = startRead(); 122 if (pass) --waitingReaders_; 123 return pass; 124 } 125 126 protected synchronized boolean startWriteFromWaitingWriter() { 127 boolean pass = startWrite(); 128 if (pass) --waitingWriters_; 129 return pass; 130 } 131 132 136 protected synchronized Signaller endRead() { 137 if (--activeReaders_ == 0 && waitingWriters_ > 0) 138 return writerLock_; 139 else 140 return null; 141 } 142 143 144 148 protected synchronized Signaller endWrite() { 149 activeWriter_ = null; 150 if (waitingReaders_ > 0 && allowReader()) 151 return readerLock_; 152 else if (waitingWriters_ > 0) 153 return writerLock_; 154 else 155 return null; 156 } 157 158 159 167 168 protected abstract class Signaller { abstract void signalWaiters(); 170 } 171 172 protected class ReaderLock extends Signaller implements Sync { 173 174 public void acquire() throws InterruptedException { 175 if (Thread.interrupted()) throw new InterruptedException (); 176 InterruptedException ie = null; 177 synchronized(this) { 178 if (!startReadFromNewReader()) { 179 for (;;) { 180 try { 181 ReaderLock.this.wait(); 182 if (startReadFromWaitingReader()) 183 return; 184 } 185 catch(InterruptedException ex){ 186 cancelledWaitingReader(); 187 ie = ex; 188 break; 189 } 190 } 191 } 192 } 193 if (ie != null) { 194 writerLock_.signalWaiters(); 198 throw ie; 199 } 200 } 201 202 203 public void release() { 204 Signaller s = endRead(); 205 if (s != null) s.signalWaiters(); 206 } 207 208 209 synchronized void signalWaiters() { ReaderLock.this.notifyAll(); } 210 211 public boolean attempt(long msecs) throws InterruptedException { 212 if (Thread.interrupted()) throw new InterruptedException (); 213 InterruptedException ie = null; 214 synchronized(this) { 215 if (msecs <= 0) 216 return startRead(); 217 else if (startReadFromNewReader()) 218 return true; 219 else { 220 long waitTime = msecs; 221 long start = System.currentTimeMillis(); 222 for (;;) { 223 try { ReaderLock.this.wait(waitTime); } 224 catch(InterruptedException ex){ 225 cancelledWaitingReader(); 226 ie = ex; 227 break; 228 } 229 if (startReadFromWaitingReader()) 230 return true; 231 else { 232 waitTime = msecs - (System.currentTimeMillis() - start); 233 if (waitTime <= 0) { 234 cancelledWaitingReader(); 235 break; 236 } 237 } 238 } 239 } 240 } 241 writerLock_.signalWaiters(); 243 if (ie != null) throw ie; 244 else return false; } 246 247 } 248 249 protected class WriterLock extends Signaller implements Sync { 250 251 public void acquire() throws InterruptedException { 252 if (Thread.interrupted()) throw new InterruptedException (); 253 InterruptedException ie = null; 254 synchronized(this) { 255 if (!startWriteFromNewWriter()) { 256 for (;;) { 257 try { 258 WriterLock.this.wait(); 259 if (startWriteFromWaitingWriter()) 260 return; 261 } 262 catch(InterruptedException ex){ 263 cancelledWaitingWriter(); 264 WriterLock.this.notify(); 265 ie = ex; 266 break; 267 } 268 } 269 } 270 } 271 if (ie != null) { 272 readerLock_.signalWaiters(); 276 throw ie; 277 } 278 } 279 280 public void release(){ 281 Signaller s = endWrite(); 282 if (s != null) s.signalWaiters(); 283 } 284 285 synchronized void signalWaiters() { WriterLock.this.notify(); } 286 287 public boolean attempt(long msecs) throws InterruptedException { 288 if (Thread.interrupted()) throw new InterruptedException (); 289 InterruptedException ie = null; 290 synchronized(this) { 291 if (msecs <= 0) 292 return startWrite(); 293 else if (startWriteFromNewWriter()) 294 return true; 295 else { 296 long waitTime = msecs; 297 long start = System.currentTimeMillis(); 298 for (;;) { 299 try { WriterLock.this.wait(waitTime); } 300 catch(InterruptedException ex){ 301 cancelledWaitingWriter(); 302 WriterLock.this.notify(); 303 ie = ex; 304 break; 305 } 306 if (startWriteFromWaitingWriter()) 307 return true; 308 else { 309 waitTime = msecs - (System.currentTimeMillis() - start); 310 if (waitTime <= 0) { 311 cancelledWaitingWriter(); 312 WriterLock.this.notify(); 313 break; 314 } 315 } 316 } 317 } 318 } 319 320 readerLock_.signalWaiters(); 321 if (ie != null) throw ie; 322 else return false; } 324 325 } 326 327 328 329 } 330 331 332 | Popular Tags |