reentrantlock.java
来自「SRI international 发布的OAA框架软件」· Java 代码 · 共 874 行 · 第 1/3 页
JAVA
874 行
/*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
* http://creativecommons.org/licenses/publicdomain
*/
package edu.emory.mathcs.backport.java.util.concurrent.locks;
import java.util.*;
import edu.emory.mathcs.backport.java.util.concurrent.*;
import edu.emory.mathcs.backport.java.util.concurrent.helpers.*;
/**
* A reentrant mutual exclusion {@link Lock} with the same basic
* behavior and semantics as the implicit monitor lock accessed using
* <tt>synchronized</tt> methods and statements, but with extended
* capabilities.
*
* <p> A <tt>ReentrantLock</tt> is <em>owned</em> by the thread last
* successfully locking, but not yet unlocking it. A thread invoking
* <tt>lock</tt> will return, successfully acquiring the lock, when
* the lock is not owned by another thread. The method will return
* immediately if the current thread already owns the lock. This can
* be checked using methods {@link #isHeldByCurrentThread}, and {@link
* #getHoldCount}.
*
* <p> The constructor for this class accepts an optional
* <em>fairness</em> parameter. When set <tt>true</tt>, under
* contention, locks favor granting access to the longest-waiting
* thread. Otherwise this lock does not guarantee any particular
* access order. Programs using fair locks accessed by many threads
* may display lower overall throughput (i.e., are slower; often much
* slower) than those using the default setting, but have smaller
* variances in times to obtain locks and guarantee lack of
* starvation. Note however, that fairness of locks does not guarantee
* fairness of thread scheduling. Thus, one of many threads using a
* fair lock may obtain it multiple times in succession while other
* active threads are not progressing and not currently holding the
* lock.
* Also note that the untimed {@link #tryLock() tryLock} method does not
* honor the fairness setting. It will succeed if the lock
* is available even if other threads are waiting.
*
* <p> It is recommended practice to <em>always</em> immediately
* follow a call to <tt>lock</tt> with a <tt>try</tt> block, most
* typically in a before/after construction such as:
*
* <pre>
* class X {
* private final ReentrantLock lock = new ReentrantLock();
* // ...
*
* public void m() {
* lock.lock(); // block until condition holds
* try {
* // ... method body
* } finally {
* lock.unlock()
* }
* }
* }
* </pre>
*
* <p>In addition to implementing the {@link Lock} interface, this
* class defines methods <tt>isLocked</tt> and
* <tt>getLockQueueLength</tt>, as well as some associated
* <tt>protected</tt> access methods that may be useful for
* instrumentation and monitoring.
*
* <p> Serialization of this class behaves in the same way as built-in
* locks: a deserialized lock is in the unlocked state, regardless of
* its state when serialized.
*
* <p> This lock supports a maximum of 2147483648 recursive locks by
* the same thread.
*
* @since 1.5
* @author Doug Lea
* @author Dawid Kurzyniec
*/
public class ReentrantLock implements Lock, java.io.Serializable,
CondVar.LockInfo {
private static final long serialVersionUID = 7373984872572414699L;
private final Impl impl;
static abstract class Impl {
protected Thread owner_ = null;
protected int holds_ = 0;
protected Impl() {}
public abstract void lockInterruptibly() throws InterruptedException;
public boolean tryLock() {
Thread caller = Thread.currentThread();
synchronized (this) {
if (owner_ == null) {
owner_ = caller;
holds_ = 1;
return true;
}
else if (caller == owner_) {
++holds_;
return true;
}
}
return false;
}
public abstract boolean tryLock(long nanos) throws InterruptedException;
public abstract void unlock();
public synchronized int getHoldCount() {
return isHeldByCurrentThread() ? holds_ : 0;
}
public synchronized boolean isHeldByCurrentThread() {
return Thread.currentThread() == owner_;
}
public synchronized boolean isLocked() {
return owner_ != null;
}
public abstract boolean isFair();
protected synchronized Thread getOwner() {
return owner_;
}
public boolean hasQueuedThreads() {
throw new UnsupportedOperationException("Use FAIR version");
}
public int getQueueLength() {
throw new UnsupportedOperationException("Use FAIR version");
}
public Collection getQueuedThreads() {
throw new UnsupportedOperationException("Use FAIR version");
}
public boolean isQueued(Thread thread) {
throw new UnsupportedOperationException("Use FAIR version");
}
}
final static class NonfairImpl extends Impl implements java.io.Serializable {
NonfairImpl() {}
public void lockInterruptibly() throws InterruptedException {
if (Thread.interrupted()) throw new InterruptedException();
Thread caller = Thread.currentThread();
synchronized (this) {
if (owner_ == null) {
owner_ = caller;
holds_ = 1;
return;
}
else if (caller == owner_) {
++holds_;
return;
}
else {
try {
do { wait(); } while (owner_ != null);
owner_ = caller;
holds_ = 1;
return;
}
catch (InterruptedException ex) {
notify();
throw ex;
}
}
}
}
public boolean tryLock(long nanos) throws InterruptedException {
if (Thread.interrupted()) throw new InterruptedException();
Thread caller = Thread.currentThread();
synchronized (this) {
if (owner_ == null) {
owner_ = caller;
holds_ = 1;
return true;
}
else if (caller == owner_) {
++holds_;
return true;
}
else if (nanos <= 0)
return false;
else {
long deadline = Utils.nanoTime() + nanos;
try {
for (; ; ) {
TimeUnit.NANOSECONDS.timedWait(this, nanos);
if (caller == owner_) {
++holds_;
return true;
}
else if (owner_ == null) {
owner_ = caller;
holds_ = 1;
return true;
}
else {
nanos = deadline - Utils.nanoTime();
if (nanos <= 0)
return false;
}
}
}
catch (InterruptedException ex) {
notify();
throw ex;
}
}
}
}
public synchronized void unlock() {
if (Thread.currentThread() != owner_)
throw new IllegalMonitorStateException("Not owner");
if (--holds_ == 0) {
owner_ = null;
notify();
}
}
public final boolean isFair() {
return false;
}
}
final static class FairImpl extends Impl implements WaitQueue.QueuedSync,
java.io.Serializable {
private final WaitQueue wq_ = new FIFOWaitQueue();
FairImpl() {}
public synchronized boolean recheck(WaitQueue.WaitNode node) {
Thread caller = Thread.currentThread();
if (owner_ == null) {
owner_ = caller;
holds_ = 1;
return true;
}
else if (caller == owner_) {
++holds_;
return true;
}
wq_.insert(node);
return false;
}
public synchronized void takeOver(WaitQueue.WaitNode node) {
// assert (holds_ == 1 && owner_ == Thread.currentThread()
owner_ = node.getOwner();
}
public void lockInterruptibly() throws InterruptedException {
if (Thread.interrupted()) throw new InterruptedException();
Thread caller = Thread.currentThread();
synchronized (this) {
if (owner_ == null) {
owner_ = caller;
holds_ = 1;
return;
}
else if (caller == owner_) {
++holds_;
return;
}
}
WaitQueue.WaitNode n = new WaitQueue.WaitNode();
n.doWait(this);
}
public boolean tryLock(long nanos) throws InterruptedException {
if (Thread.interrupted()) throw new InterruptedException();
Thread caller = Thread.currentThread();
synchronized (this) {
if (owner_ == null) {
owner_ = caller;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?