1 7 package com.ibm.icu.impl; 8 9 11 12 33 public class ICURWLock { 34 private Object writeLock = new Object (); 35 private Object readLock = new Object (); 36 private int wwc; private int rc; private int wrc; 40 private Stats stats = new Stats(); 42 45 public final static class Stats { 46 49 public int _rc; 50 51 54 public int _mrc; 55 56 59 public int _wrc; 61 64 public int _wc; 65 66 69 public int _wwc; 70 71 private Stats() { 72 } 73 74 private Stats(int rc, int mrc, int wrc, int wc, int wwc) { 75 this._rc = rc; 76 this._mrc = mrc; 77 this._wrc = wrc; 78 this._wc = wc; 79 this._wwc = wwc; 80 } 81 82 private Stats(Stats rhs) { 83 this(rhs._rc, rhs._mrc, rhs._wrc, rhs._wc, rhs._wwc); 84 } 85 86 89 public String toString() { 90 return " rc: " + _rc + 91 " mrc: " + _mrc + 92 " wrc: " + _wrc + 93 " wc: " + _wc + 94 " wwc: " + _wwc; 95 } 96 } 97 98 101 public synchronized Stats resetStats() { 102 Stats result = stats; 103 stats = new Stats(); 104 return result; 105 } 106 107 110 public synchronized Stats clearStats() { 111 Stats result = stats; 112 stats = null; 113 return result; 114 } 115 116 119 public synchronized Stats getStats() { 120 return stats == null ? null : new Stats(stats); 121 } 122 123 125 private synchronized boolean gotRead() { 126 ++rc; 127 if (stats != null) { 128 ++stats._rc; 129 if (rc > 1) ++stats._mrc; 130 } 131 return true; 132 } 133 134 private synchronized boolean getRead() { 135 if (rc >= 0 && wwc == 0) { 136 return gotRead(); 137 } 138 ++wrc; 139 return false; 140 } 141 142 private synchronized boolean retryRead() { 143 if (stats != null) ++stats._wrc; 144 if (rc >= 0 && wwc == 0) { 145 --wrc; 146 return gotRead(); 147 } 148 return false; 149 } 150 151 private synchronized boolean finishRead() { 152 if (rc > 0) { 153 return (0 == --rc && wwc > 0); 154 } 155 throw new IllegalStateException ("no current reader to release"); 156 } 157 158 private synchronized boolean gotWrite() { 159 rc = -1; 160 if (stats != null) { 161 ++stats._wc; 162 } 163 return true; 164 } 165 166 private synchronized boolean getWrite() { 167 if (rc == 0) { 168 return gotWrite(); 169 } 170 ++wwc; 171 return false; 172 } 173 174 private synchronized boolean retryWrite() { 175 if (stats != null) ++stats._wwc; 176 if (rc == 0) { 177 --wwc; 178 return gotWrite(); 179 } 180 return false; 181 } 182 183 private static final int NOTIFY_NONE = 0; 184 private static final int NOTIFY_WRITERS = 1; 185 private static final int NOTIFY_READERS = 2; 186 187 private synchronized int finishWrite() { 188 if (rc < 0) { 189 rc = 0; 190 if (wwc > 0) { 191 return NOTIFY_WRITERS; 192 } else if (wrc > 0) { 193 return NOTIFY_READERS; 194 } else { 195 return NOTIFY_NONE; 196 } 197 } 198 throw new IllegalStateException ("no current writer to release"); 199 } 200 201 211 public void acquireRead() { 212 if (!getRead()) { 213 for (;;) { 214 try { 215 synchronized (readLock) { 216 readLock.wait(); 217 } 218 if (retryRead()) { 219 return; 220 } 221 } 222 catch (InterruptedException e) { 223 } 224 } 225 } 226 } 227 228 236 public void releaseRead() { 237 if (finishRead()) { 238 synchronized (writeLock) { 239 writeLock.notify(); 240 } 241 } 242 } 243 244 255 public void acquireWrite() { 256 if (!getWrite()) { 257 for (;;) { 258 try { 259 synchronized (writeLock) { 260 writeLock.wait(); 261 } 262 if (retryWrite()) { 263 return; 264 } 265 } 266 catch (InterruptedException e) { 267 } 268 } 269 } 270 } 271 272 281 public void releaseWrite() { 282 switch (finishWrite()) { 283 case NOTIFY_WRITERS: 284 synchronized (writeLock) { 285 writeLock.notify(); 286 } 287 break; 288 case NOTIFY_READERS: 289 synchronized (readLock) { 290 readLock.notifyAll(); 291 } 292 break; 293 case NOTIFY_NONE: 294 break; 295 } 296 } 297 } 298 | Popular Tags |