1 6 21 22 package de.schlichtherle.io; 23 24 import de.schlichtherle.util.ThreadLocalCounter; 25 26 import java.util.logging.Level ; 27 import java.util.logging.Logger ; 28 29 58 final class ReentrantReadWriteLock implements ReadWriteLock { 59 60 private static final String CLASS_NAME 61 = "de/schlichtherle/io/ReentrantReadWriteLock".replace('/', '.'); private static final Logger logger 63 = Logger.getLogger(CLASS_NAME, CLASS_NAME); 64 65 private final ReadLock readLock = new ReadLock(); 66 private final WriteLock writeLock = new WriteLock(); 67 68 private int totalWriteLockCount; 69 private int totalReadLockCount; 70 71 75 80 public ReentrantLock readLock() { 81 return readLock; 82 } 83 84 89 public ReentrantLock writeLock() { 90 return writeLock; 91 } 92 93 private synchronized void lockRead() { 94 final int threadWriteLockCount = writeLock.lockCount(); 98 if (threadWriteLockCount <= 0) { while (totalWriteLockCount - threadWriteLockCount > 0) { 101 try { 102 wait(); 103 } catch (InterruptedException ex) { 104 logger.log(Level.FINE, "interrupted", ex); 105 logger.log(Level.FINE, "continuing"); 106 } 107 } 108 } 109 totalReadLockCount++; 110 } 111 112 private synchronized void lockReadInterruptibly() 113 throws InterruptedException { 114 final int threadWriteLockCount = writeLock.lockCount(); 118 if (threadWriteLockCount <= 0) { while (totalWriteLockCount - threadWriteLockCount > 0) { 121 wait(); 122 } 123 } 124 totalReadLockCount++; 125 } 126 127 private synchronized boolean tryLockRead() { 128 final int threadWriteLockCount = writeLock.lockCount(); 132 if (threadWriteLockCount <= 0) { if (totalWriteLockCount - threadWriteLockCount > 0) { 135 return false; 136 } 137 } 138 totalReadLockCount++; 139 return true; 140 } 141 142 private synchronized void unlockRead() { 143 totalReadLockCount--; 144 notifyAll(); 145 } 146 147 private synchronized void lockWrite() { 148 final int threadWriteLockCount = writeLock.lockCount(); 152 if (threadWriteLockCount <= 0) { while (totalReadLockCount > 0 157 || totalWriteLockCount - threadWriteLockCount > 0) { 158 try { 159 wait(); 160 } catch (InterruptedException ex) { 161 logger.log(Level.FINE, "interrupted", ex); 162 logger.log(Level.FINE, "continuing"); 163 } 164 } 165 } 166 totalWriteLockCount++; 167 } 168 169 private synchronized void lockWriteInterruptibly() 170 throws InterruptedException { 171 final int threadWriteLockCount = writeLock.lockCount(); 175 if (threadWriteLockCount <= 0) { while (totalReadLockCount > 0 180 || totalWriteLockCount - threadWriteLockCount > 0) { 181 wait(); 182 } 183 } 184 totalWriteLockCount++; 185 } 186 187 private synchronized boolean tryLockWrite() { 188 final int threadWriteLockCount = writeLock.lockCount(); 192 if (threadWriteLockCount <= 0) { if (totalReadLockCount > 0 197 || totalWriteLockCount - threadWriteLockCount > 0) { 198 return false; 199 } 200 } 201 totalWriteLockCount++; 202 return true; 203 } 204 205 private synchronized void unlockWrite() { 206 totalWriteLockCount--; 207 notifyAll(); 208 } 209 210 214 private static abstract class AbstractLock 215 extends ThreadLocalCounter 216 implements ReentrantLock { 217 218 public final boolean isLocked() { 219 return getCounter() > 0; 220 } 221 222 public final int lockCount() { 223 return getCounter(); 224 } 225 226 public void lock() { 227 increment(); 228 } 229 230 public void unlock() { 231 int lockCount = getCounter(); 232 if (lockCount <= 0) 233 throw new IllegalMonitorStateException (); 234 setCounter(lockCount - 1); 235 } 236 } 237 238 private class ReadLock extends AbstractLock { 239 public void lock() { 240 lockRead(); 241 super.lock(); 242 } 243 244 public void lockInterruptibly() throws InterruptedException { 245 lockReadInterruptibly(); 246 super.lock(); 247 } 248 249 public boolean tryLock() { 250 boolean locked = tryLockRead(); 251 if (locked) 252 super.lock(); 253 return locked; 254 } 255 256 public void unlock() { 257 super.unlock(); 258 unlockRead(); 259 } 260 } 261 262 private class WriteLock extends AbstractLock { 263 public void lock() { 264 lockWrite(); 265 super.lock(); 266 } 267 268 public void lockInterruptibly() throws InterruptedException { 269 lockWriteInterruptibly(); 270 super.lock(); 271 } 272 273 public boolean tryLock() { 274 boolean locked = tryLockWrite(); 275 if (locked) 276 super.lock(); 277 return locked; 278 } 279 280 public void unlock() { 281 super.unlock(); 282 unlockWrite(); 283 } 284 } 285 } 286 | Popular Tags |