1 6 7 package org.apache.beehive.netui.util.internal.concurrent; 8 9 import java.util.*; 10 11 79 class ReentrantLock implements Lock, java.io.Serializable , 80 CondVar.LockInfo { 81 private static final long serialVersionUID = 7373984872572414699L; 82 83 private final Impl impl; 84 85 static abstract class Impl { 86 protected Thread owner_ = null; 87 protected int holds_ = 0; 88 89 protected Impl() {} 90 91 public abstract void lockInterruptibly() throws InterruptedException ; 92 93 public boolean tryLock() { 94 Thread caller = Thread.currentThread(); 95 synchronized (this) { 96 if (owner_ == null) { 97 owner_ = caller; 98 holds_ = 1; 99 return true; 100 } 101 else if (caller == owner_) { 102 ++holds_; 103 return true; 104 } 105 } 106 return false; 107 } 108 109 public abstract boolean tryLock(long nanos) throws InterruptedException ; 110 111 public abstract void unlock(); 112 113 public synchronized int getHoldCount() { 114 return isHeldByCurrentThread() ? holds_ : 0; 115 } 116 117 public synchronized boolean isHeldByCurrentThread() { 118 return Thread.currentThread() == owner_; 119 } 120 121 public synchronized boolean isLocked() { 122 return owner_ != null; 123 } 124 125 public abstract boolean isFair(); 126 127 protected synchronized Thread getOwner() { 128 return owner_; 129 } 130 131 public boolean hasQueuedThreads() { 132 throw new UnsupportedOperationException ("Use FAIR version"); 133 } 134 135 public int getQueueLength() { 136 throw new UnsupportedOperationException ("Use FAIR version"); 137 } 138 139 public Collection getQueuedThreads() { 140 throw new UnsupportedOperationException ("Use FAIR version"); 141 } 142 143 public boolean isQueued(Thread thread) { 144 throw new UnsupportedOperationException ("Use FAIR version"); 145 } 146 } 147 148 final static class NonfairImpl extends Impl implements java.io.Serializable { 149 150 NonfairImpl() {} 151 152 public void lockInterruptibly() throws InterruptedException { 153 if (Thread.interrupted()) throw new InterruptedException (); 154 Thread caller = Thread.currentThread(); 155 synchronized (this) { 156 if (owner_ == null) { 157 owner_ = caller; 158 holds_ = 1; 159 return; 160 } 161 else if (caller == owner_) { 162 ++holds_; 163 return; 164 } 165 else { 166 try { 167 do { wait(); } while (owner_ != null); 168 owner_ = caller; 169 holds_ = 1; 170 return; 171 } 172 catch (InterruptedException ex) { 173 notify(); 174 throw ex; 175 } 176 } 177 } 178 } 179 180 public boolean tryLock(long nanos) throws InterruptedException { 181 if (Thread.interrupted()) throw new InterruptedException (); 182 Thread caller = Thread.currentThread(); 183 184 synchronized (this) { 185 if (owner_ == null) { 186 owner_ = caller; 187 holds_ = 1; 188 return true; 189 } 190 else if (caller == owner_) { 191 ++holds_; 192 return true; 193 } 194 else if (nanos <= 0) 195 return false; 196 else { 197 long deadline = Utils.nanoTime() + nanos; 198 try { 199 for (; ; ) { 200 TimeUnit.NANOSECONDS.timedWait(this, nanos); 201 if (caller == owner_) { 202 ++holds_; 203 return true; 204 } 205 else if (owner_ == null) { 206 owner_ = caller; 207 holds_ = 1; 208 return true; 209 } 210 else { 211 nanos = deadline - Utils.nanoTime(); 212 if (nanos <= 0) 213 return false; 214 } 215 } 216 } 217 catch (InterruptedException ex) { 218 notify(); 219 throw ex; 220 } 221 } 222 } 223 } 224 225 public synchronized void unlock() { 226 if (Thread.currentThread() != owner_) 227 throw new IllegalMonitorStateException ("Not owner"); 228 229 if (--holds_ == 0) { 230 owner_ = null; 231 notify(); 232 } 233 } 234 235 public final boolean isFair() { 236 return false; 237 } 238 } 239 240 final static class FairImpl extends Impl implements WaitQueue.QueuedSync, 241 java.io.Serializable { 242 243 private final WaitQueue wq_ = new FIFOWaitQueue(); 244 245 FairImpl() {} 246 247 public synchronized boolean recheck(WaitQueue.WaitNode node) { 248 Thread caller = Thread.currentThread(); 249 if (owner_ == null) { 250 owner_ = caller; 251 holds_ = 1; 252 return true; 253 } 254 else if (caller == owner_) { 255 ++holds_; 256 return true; 257 } 258 wq_.insert(node); 259 return false; 260 } 261 262 public synchronized void takeOver(WaitQueue.WaitNode node) { 263 owner_ = node.getOwner(); 265 } 266 267 public void lockInterruptibly() throws InterruptedException { 268 if (Thread.interrupted()) throw new InterruptedException (); 269 Thread caller = Thread.currentThread(); 270 synchronized (this) { 271 if (owner_ == null) { 272 owner_ = caller; 273 holds_ = 1; 274 return; 275 } 276 else if (caller == owner_) { 277 ++holds_; 278 return; 279 } 280 } 281 WaitQueue.WaitNode n = new WaitQueue.WaitNode(); 282 n.doWait(this); 283 } 284 285 public boolean tryLock(long nanos) throws InterruptedException { 286 if (Thread.interrupted()) throw new InterruptedException (); 287 Thread caller = Thread.currentThread(); 288 synchronized (this) { 289 if (owner_ == null) { 290 owner_ = caller; 291 holds_ = 1; 292 return true; 293 } 294 else if (caller == owner_) { 295 ++holds_; 296 return true; 297 } 298 } 299 WaitQueue.WaitNode n = new WaitQueue.WaitNode(); 300 return n.doTimedWait(this, nanos); 301 } 302 303 protected synchronized WaitQueue.WaitNode getSignallee(Thread caller) { 304 if (caller != owner_) 305 throw new IllegalMonitorStateException ("Not owner"); 306 if (holds_ >= 2) { --holds_; 309 return null; 310 } 311 WaitQueue.WaitNode w = wq_.extract(); 313 if (w == null) { owner_ = null; 315 holds_ = 0; 316 } 317 return w; 318 } 319 320 public void unlock() { 321 Thread caller = Thread.currentThread(); 322 for (;;) { 323 WaitQueue.WaitNode w = getSignallee(caller); 324 if (w == null) return; if (w.signal(this)) return; } 327 } 328 329 public final boolean isFair() { 330 return true; 331 } 332 333 public synchronized boolean hasQueuedThreads() { 334 return wq_.hasNodes(); 335 } 336 337 public synchronized int getQueueLength() { 338 return wq_.getLength(); 339 } 340 341 public synchronized Collection getQueuedThreads() { 342 return wq_.getWaitingThreads(); 343 } 344 345 public synchronized boolean isQueued(Thread thread) { 346 return wq_.isWaiting(thread); 347 } 348 } 349 350 354 public ReentrantLock() { 355 impl = new NonfairImpl(); 356 } 357 358 363 public ReentrantLock(boolean fair) { 364 impl = (fair)? (Impl)new FairImpl() : new NonfairImpl(); 365 } 366 367 368 383 public void lock() { 384 boolean wasInterrupted = false; 385 while (true) { 386 try { 387 impl.lockInterruptibly(); 388 if (wasInterrupted) { 389 Thread.currentThread().interrupt(); 390 } 391 return; 392 } 393 catch (InterruptedException e) { 394 wasInterrupted = true; 395 } 396 } 397 } 398 399 446 public void lockInterruptibly() throws InterruptedException { 447 impl.lockInterruptibly(); 448 } 449 450 477 public boolean tryLock() { 478 return impl.tryLock(); 479 } 480 481 555 public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException { 556 return impl.tryLock(unit.toNanos(timeout)); 557 } 558 559 570 public void unlock() { 571 impl.unlock(); 572 } 573 574 613 public Condition newCondition() { 614 return new CondVar(this); 615 } 616 617 647 public int getHoldCount() { 648 return impl.getHoldCount(); 649 } 650 651 693 public boolean isHeldByCurrentThread() { 694 return impl.isHeldByCurrentThread(); 695 } 696 697 704 public boolean isLocked() { 705 return impl.isLocked(); 706 } 707 708 712 public final boolean isFair() { 713 return impl.isFair(); 714 } 715 716 725 protected Thread getOwner() { 726 return impl.getOwner(); 727 } 728 729 739 public final boolean hasQueuedThreads() { 740 return impl.hasQueuedThreads(); 741 } 742 743 744 755 public final boolean hasQueuedThread(Thread thread) { 756 return impl.isQueued(thread); 757 } 758 759 760 769 public final int getQueueLength() { 770 return impl.getQueueLength(); 771 } 772 773 783 protected Collection getQueuedThreads() { 784 return impl.getQueuedThreads(); 785 } 786 787 810 833 858 865 public String toString() { 866 Thread owner = getOwner(); 867 return super.toString() + ((owner == null) ? 868 "[Unlocked]" : 869 "[Locked by thread " + owner.getName() + "]"); 870 } 871 } 872 | Popular Tags |