1 10 11 package com.triactive.jdo.util; 12 13 import org.apache.log4j.Category; 14 15 16 34 35 public class ReadWriteLock 36 { 37 private static final Category LOG = Category.getInstance(ReadWriteLock.class); 38 39 private static final int WAIT_LOG_INTERVAL = 5000; 40 41 42 private ThreadLocal readLocksByThread; 43 44 45 private int readLocks; 46 47 48 private int writeLocks; 49 50 51 private Thread writeLockedBy; 52 53 54 57 58 private static class Count 59 { 60 public int value = 0; 61 } 62 63 64 67 68 public ReadWriteLock() 69 { 70 readLocksByThread = new ThreadLocal () 71 { 72 public Object initialValue() 73 { 74 return new Count(); 75 } 76 }; 77 78 readLocks = 0; 79 writeLocks = 0; 80 writeLockedBy = null; 81 } 82 83 84 94 95 public synchronized void readLock() throws InterruptedException 96 { 97 Thread me = Thread.currentThread(); 98 Count myReadLocks = (Count)readLocksByThread.get(); 99 100 if (writeLockedBy != me) 101 { 102 while (writeLocks > 0) 103 { 104 wait(WAIT_LOG_INTERVAL); 105 106 if (writeLocks > 0) 107 LOG.debug("Still waiting for read lock on " + this, new InterruptedException ()); 108 } 109 } 110 111 ++readLocks; 112 ++myReadLocks.value; 113 } 114 115 116 129 130 public synchronized void writeLock() throws InterruptedException 131 { 132 Thread me = Thread.currentThread(); 133 Count myReadLocks = (Count)readLocksByThread.get(); 134 135 if (myReadLocks.value > 0) 136 throw new IllegalStateException ("Thread already holds a read lock"); 137 138 if (writeLockedBy != me) 139 { 140 while (writeLocks > 0 || readLocks > 0) 141 { 142 wait(WAIT_LOG_INTERVAL); 143 144 if (writeLocks > 0 || readLocks > 0) 145 LOG.debug("Still waiting for write lock on " + this, new InterruptedException ()); 146 } 147 148 writeLockedBy = me; 149 } 150 151 ++writeLocks; 152 } 153 154 155 159 160 public synchronized void unlock() 161 { 162 Thread me = Thread.currentThread(); 163 Count myReadLocks = (Count)readLocksByThread.get(); 164 165 if (myReadLocks.value > 0) 166 { 167 --myReadLocks.value; 168 --readLocks; 169 } 170 else if (writeLockedBy == me) 171 { 172 if (writeLocks > 0) 173 { 174 if (--writeLocks == 0) 175 writeLockedBy = null; 176 } 177 } 178 179 notifyAll(); 180 } 181 182 183 public String toString() 184 { 185 StringBuffer s = new StringBuffer (super.toString()); 186 187 s.append(": readLocks = ").append(readLocks) 188 .append(", writeLocks = ").append(writeLocks) 189 .append(", writeLockedBy = ").append(writeLockedBy); 190 191 return s.toString(); 192 } 193 } 194 | Popular Tags |