/*
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/publicdomain/zero/1.0/
/
package java.util.concurrent.locks;
import java.util.concurrent.TimeUnit;
import java.util.Collection;
A reentrant mutual exclusion {@link Lock} with the same basic
A reentrant mutual exclusion {@link Lock} with the same basic
behavior and semantics as the implicit monitor lock accessed using
{@code synchronized} methods and statements, but with extended
capabilities.
可重入的独占锁 同 implicit 监视器锁 拥有相同的基本行为和语义
A {@code ReentrantLock} is owned by the thread last
successfully locking, but not yet unlocking it. A thread invoking
{@code lock} 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}.
The constructor for this class accepts an optional
fairness parameter. When set {@code true}, 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()} method does not
honor the fairness setting. It will succeed if the lock
is available even if other threads are waiting.
It is recommended practice to always immediately
follow a call to {@code lock} with a {@code try} block, most
typically in a before/after construction such as:
{@code
class X {
private final ReentrantLock lock = new ReentrantLock();
// ...public void m() {
lock.lock(); // block until condition holds
try {
// ... method body
} finally {
lock.unlock()
}
}
}}
In addition to implementing the {@link Lock} interface, this
class defines a number of {@code public} and {@code protected}
methods for inspecting the state of the lock. Some of these
methods are only useful for instrumentation and monitoring.
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.
This lock supports a maximum of 2147483647 recursive locks by
the same thread. Attempts to exceed this limit result in
{@link Error} throws from locking methods./**
behavior and semantics as the implicit monitor lock accessed using
{@code synchronized} methods and statements, but with extended
capabilities.
可重入的独占锁 同 implicit 监视器锁 拥有相同的基本行为和语义
A {@code ReentrantLock} is owned by the thread last
successfully locking, but not yet unlocking it. A thread invoking
{@code lock} 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}.
The constructor for this class accepts an optional
fairness parameter. When set {@code true}, 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()} method does not
honor the fairness setting. It will succeed if the lock
is available even if other threads are waiting.
It is recommended practice to always immediately
follow a call to {@code lock} with a {@code try} block, most
typically in a before/after construction such as:
{@code
class X {
private final ReentrantLock lock = new ReentrantLock();
// ...public void m() {
lock.lock(); // block until condition holds
try {
// ... method body
} finally {
lock.unlock()
}
}
}}
In addition to implementing the {@link Lock} interface, this
class defines a number of {@code public} and {@code protected}
methods for inspecting the state of the lock. Some of these
methods are only useful for instrumentation and monitoring.
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.
This lock supports a maximum of 2147483647 recursive locks by
the same thread. Attempts to exceed this limit result in
{@link Error} throws from locking methods.
重入式的相互排斥{@链接锁},基本相同的
的行为和语义,与使用
{@code synchronized}方法和语句,但带有扩展的
能力。
一个{@code ReentrantLock}是拥有的线程。
成功锁定,但还没有解锁。调用的线程
{@code lock}将返回,成功获取锁,当
锁不属于其他线程。该方法将返回
如果当前线程已经拥有了锁,那么就会立即使用。这种情况下,可以
使用方法{@link #isHeldByCurrentThread}和{@link
#getHoldCount}。
这个类的构造函数接受一个可选的
公平性参数。 当设置{@code true}时,在
争论的是,锁具有利于让等待时间最长的人进入。
线程。 否则,此锁并不能保证任何特定的
访问顺序。 使用由多个线程访问的公平锁的程序
可能显示出较低的总体吞吐量(即速度较慢;通常要慢得多。
比那些使用默认设置的人更慢),但比使用默认设置的人的速度更慢。
差异化的时间来获取锁具和保证不被锁住
饿死了。但请注意,锁定的公平性并不能保证
线程调度的公平性。因此,许多线程中的一个使用
公道的锁,可以连续多次获得,而其他
活动中的线程没有进展,目前不持有
锁定。
另外要注意的是,不定时的{@link #tryLock()}方法并没有
尊重公平性设置。它将成功,如果锁定
即使其他线程在等待,也是可用的。
推荐的做法是:总是立即。
在调用{@code lock}后,使用{@code try}块,大部分的
通常是在前后结构中,例如。
{@code
X类 {
private final ReentrantLock Lock = new ReentrantLock();
// ...public void m() {
lock.lock(); ///阻塞,直到条件成立为止。
试试
///...方法正文
} 最后 {
解锁()
}
}
}}
除了实现{@link Lock}接口外,这个
类定义了一些{@code public}和{@code protected}。
检查锁的状态的方法。 其中有些方法是:
方法只对仪表和监控有用。
该类的序列化行为与内置的方法相同。
锁:反序列化的锁是处于未锁状态,无论
其序列化时的状态。
此锁最多支持2147483647个递归锁,通过
同一条线程。试图超过这一限制的结果是
{@link Error}从锁定方法抛出。
的行为和语义,就像隐式监控锁一样,使用
{@code synchronized}方法和语句,但带有扩展的
能力。
可重入的独占锁 同隐含 监视器锁 拥有相同的基本行为和语义
一个{@code ReentrantLock}是拥有的线程,由最后一个
成功锁定,但还没有解锁。调用的线程
{@code lock}将返回,成功获取锁,当
锁不属于其他线程。该方法将返回
如果当前线程已经拥有了锁,那么就会立即使用。这种情况下,可以
使用方法{@link #isHeldByCurrentThread}和{@link
#getHoldCount}。
这个类的构造函数接受一个可选的
公平性参数。 当设置{@code true}时,在
争论的是,锁具有利于让等待时间最长的人进入。
线程。 否则,此锁并不能保证任何特定的
访问顺序。 使用由多个线程访问的公平锁的程序
可能显示出较低的总体吞吐量(即速度较慢;通常要慢得多。
比那些使用默认设置的人更慢),但比使用默认设置的人的速度更慢。
差异化的时间来获取锁具和保证不被锁住
饿死了。但请注意,锁定的公平性并不能保证
线程调度的公平性。因此,许多线程中的一个使用
公道的锁,可以连续多次获得,而其他
活动中的线程没有进展,目前不持有
锁定。
另外要注意的是,不定时的{@link #tryLock()}方法并没有
尊重公平性设置。它将成功,如果锁定
即使其他线程在等待,也是可用的。
推荐的做法是:总是立即。
在调用{@code lock}后,使用{@code try}块,大部分的
通常是在前后结构中,例如。
{@code
X类 {
private final ReentrantLock Lock = new ReentrantLock();
// ...public void m() {
lock.lock(); ///阻塞,直到条件成立为止。
试试
///...方法正文
} 最后 {
解锁()
}
}
}}
除了实现{@link Lock}接口外,这个
类定义了一些{@code public}和{@code protected}。
检查锁的状态的方法。 其中有些方法是:
方法只对仪表和监控有用。
该类的序列化行为与内置的方法相同。
锁:反序列化的锁是处于未锁状态,无论
其时的状态
此锁最多支持2147483647次递归锁,通过
同一条线程。试图超过这一限制的结果是
{@link Error}从锁定方法中抛出。
通过www.DeepL.com/Translator(免费版)翻译
公平锁,意味着无用的唤醒会比较少,但是相对非公平锁,效率会有所下降!
@since 1.5
@author Doug Lea
/
public class ReentrantLock implements Lock, java.io.Serializable {
private static final long serialVersionUID = 7373984872572414699L;
/** Synchronizer providing all implementation mechanics/
private final Sync sync;
/**
Base of synchronization control for this lock. Subclassed
into fair and nonfair versions below. Uses AQS state to
represent the number of holds on the lock.
该锁的同步控制基础。子类分为下面的公平和非公平版本。使用AQS状态来代表锁上的持有数量。
/
abstract static class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = -5179523762034025860L;
/**
Performs {@link Lock#lock}. The main reason for subclassing
is to allow fast path for nonfair version.
执行{@link Lock#lock}。子类化的主要原因是为了让非公平版的快速通道。
/
abstract void lock();
/**
Performs non-fair tryLock. tryAcquire is implemented in
subclasses, but both need nonfair try for trylock method.
执行非公平的tryLock。 tryAcquire由子类实现,但都需要非公平的trylock方法。
/
可以看到此方法仅仅是做一个快速的尝试,成功则;不会等待。
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) { 还未被占用,AQS还未初始化
if (compareAndSetState(0, acquires)) { cas设置资源量,以免突然之间又进来一个线程
setExclusiveOwnerThread(current); 设置线程拥有者,setExclusiveOwnerThread是AQS的父类AbstractOwnableSynchronizer接口定义的方法,
return true; 成功返回
}
}
else if (current == getExclusiveOwnerThread()) { 如果目前正在占用同步器,
int nextc = c + acquires; 那么直接重入,
if (nextc < 0) // overflow 如果重入次数太多了,
throw new Error("Maximum lock count exceeded"); 那么抛异常,(只能够通过业务规范规则的方式来避免这种极端情况)
setState(nextc); 改变资源量
return true; 返回true
}
return false; 表示快速方式 获取失败。
}
protected final boolean tryRelease(int releases) { 注意是protected方法,可以被子类复写
int c = getState() - releases;
if (Thread.currentThread() != getExclusiveOwnerThread()) 如果当前线程不是同步器owner,那么是非法状态,抛异常
throw new IllegalMonitorStateException();
boolean free = false; 默认是失败
if (c == 0) {
free = true; 只有完全释放了,才算tryRelease成功
setExclusiveOwnerThread(null); 完全释放了,同时同步器owner 为空,表示其他线程可以进入
}
setState(c); 不管是否完全释放, 都释放一定的资源量,
return free;
}
是否被当前线程 独占了同步器
protected final boolean isHeldExclusively() { 实现了AQS的isHeldExclusively方法
// While we must in general read state before owner,
// we don't need to do so to check if current thread is owner
虽然一般来说,我们必须先看状态,再看拥有者。 我们不需要这样做,以检查当前的线程是否是所有者。why?大概因为它只会在条件对象中被调用,而条件对象是只适用于独占模式的,所以同步器 只能被一个线程占用。
return getExclusiveOwnerThread() == Thread.currentThread();
}
final ConditionObject newCondition() {
return new ConditionObject();
}
// Methods relayed from outer class 从外部类转发过来的方法; outer class 是指Enclosing class?
final Thread getOwner() {
return getState() == 0 ? null : getExclusiveOwnerThread(); 获取所有者
}
final int getHoldCount() {
return isHeldExclusively() ? getState() : 0; 独占模式下,才返回重入次数,
}
final boolean isLocked() { 当前同步器是否被锁上了
return getState() != 0;
}
/**
Reconstitutes the instance from a stream (that is, deserializes it).
从流中,重新构成实例
/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
s.defaultReadObject();
setState(0); // reset to unlocked state
}
}
/**
Sync object for non-fair locks 非公平版本
/
static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;
/**
Performs lock. Try immediate barge, backing up to normal
acquire on failure.
锁定同步器,也就是给同步器上锁,让其他线程无法进入
先尝试立即的闯入,(在没有竞争的时候,这个很简单有效),闯入失败则退回到acquire
/
final void lock() {
if (compareAndSetState(0, 1)) // 先简单的尝试获取1个资源, 不管是否有线程在等待
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1); // 这个方法其实会调用下面的tryAcquire,然后是调用nonfairTryAcquire
注意 这里需要的资源是1
}
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires); 非公平的方式实现AQS的tryAcquire方法
}
}
/**
Sync object for fair locks 公平锁的同步对象
/
static final class FairSync extends Sync {
private static final long serialVersionUID = -3000897897090466540L;
final void lock() {
acquire(1); 注意 这里需要的资源是1; 这个方法其实会调用下面的tryAcquire
}
/**
Fair version of tryAcquire. Don't grant access unless
recursive call or no waiters or is first.
公平版的tryAcquire。 除非是递归调用或没有服务员或者是第一个,否则不要授予访问权限。
/
其实两个版本的 tryAcquire 区别在于c == 0时候的处理。
公平锁需要保证同步队列的head就是当前线程或者 目前为空; —— 这样; 差别几乎就是一个hasQueuedPredecessors,后面其实都一样,都是简单的判断是否被独占,然后..
公平就是说,你新过来的线程需要先排队,当然,如果队列为空,那么自然不要排队; 其实我感觉只需要检查一下队列是否为空即可,不为空则表示已有竞争,state肯定不为0,然后就滚去排队;
有一种情况是,队列确实不为空,比如两个节点:head-tail,但是此时tail 刚刚被取消了,那么...
非公平就是说,你新过来的线程不需要先排队,而是直接和老二竞争,当然,如果队列为空,那么自然不要排队,也没有竞争的问题
hasQueuedPredecessors 是一个特别的方法: c == 0的情况下,同步队列仍然可能存在 节点?仍需要判断前面是否已有节点入队? 这个可能是对应一种极端的情况,就是 刚刚比较完, 后面突然立马进来了几个线程.. 或者就是head已经(由于中断、超时等原因)释放,state被设置为0,但node未来得及出队..
更新: !hasQueuedPredecessors 其实就是判断是否队列为空或者当前是head或head.next;就是说,是第二个,那么是有资格进行立即获取的,那么并不违反公平性。
更新: !hasQueuedPredecessors 其实就是判断是否 没有竞争 或者 队列为空但已经有一个其他的线程正在执行;
AQS的acquire方法中,首次执行tryAcquire的时候,线程可能还未入队,这样做的原因是,如果没有竞争,那就不用初始化队列了!是一个快速的方式!
其实acquireQueued方法中,每次被唤醒都会先判断前任是不是head,然后再调用tryAcquire。就是说对于非公平锁,还是需要排队的! 和公平锁的差别,基本上是非常非常的细微,———— 所谓不公平,几乎仅仅就是 首次执行acquire的时候 不公平 !!
总结
非公平锁和公平锁的两处不同 (记住, 就是两点区别):
1 非公平锁在调用 lock 后,首先就会调用 CAS 进行一次抢锁,如果这个时候恰巧锁没有被占用,那么直接就获取到锁返回了。
2 非公平锁在 CAS 失败后,和公平锁一样都会进入到 tryAcquire 方法,在 tryAcquire 方法中,如果发现锁这个时候被释放了(state == 0),非公平锁会直接 CAS 抢锁,但是公平锁会判断等待队列是否有线程处于等待状态,如果有则不去抢锁,乖乖排到后面。
公平锁和非公平锁就这两点区别,如果这两次 CAS 都不成功,那么后面非公平锁和公平锁是一样的,都要进入到阻塞队列等待唤醒。
相对来说,非公平锁会有更好的性能,因为它的吞吐量比较大。当然,非公平锁让获取锁的时间变得更加不确定,可能会导致在阻塞队列中的线程长期处于饥饿状态, 因为它可能导致了某些线程 需要等待更久,造成饥饿!。
为什么 非公平锁会有更好的性能,因为它的吞吐量比较大 ? 这个其实要看一下锁的释放:
public final boolean release(int arg) {
if (tryRelease(arg)) {
Node h = head;
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);
return true;
}
return false;
}
可以看到,如果线程L1 执行tryRelease成功了,那么state 应该就是0,但是此时非公平锁L3进来了开始lock(), 而release方法内部的unparkSuccessor 还未执行,head的next(假设是L2) 还未唤醒(因为可能还未执行到那一行); 这样L3 不用阻塞,L2 也可能不用唤醒,当然,也可能L2 可能被唤醒,但是又被阻塞..
因为它可以使总体的 park unpark 时间更少,减少总体的阻塞时间,虽然造成了一些不公平,但是它确实
作者:小北觅
链接:https://www.jianshu.com/p/2ada27eee90b
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) { 还未有其他线程占用同步器, 比如 还没有竞争、或刚好释放了
if (!hasQueuedPredecessors() && 没有已经入队的前任
compareAndSetState(0, acquires)) { cas成功
setExclusiveOwnerThread(current); 那么占用之
return true;
}
}
else if (current == getExclusiveOwnerThread()) { 当前线程就是独占同步器的所有者
int nextc = c + acquires; 增加指定的资源量
if (nextc < 0) 如果整数溢出了
throw new Error("Maximum lock count exceeded"); 就抛异常
setState(nextc);
return true;
}
其实这里应该还有个else, 就是c>0且当前线程不是同步器所有者,那么其实也是 false
return false;
}
}
/**
Creates an instance of {@code ReentrantLock}.
This is equivalent to using {@code ReentrantLock(false)}.
/
public ReentrantLock() {
sync = new NonfairSync();
}
/**
Creates an instance of {@code ReentrantLock} with the
given fairness policy.
@param fair {@code true} if this lock should use a fair ordering policy
/
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
/**
Acquires the lock.
Acquires the lock if it is not held by another thread and returns
immediately, setting the lock hold count to one.
If the current thread already holds the lock then the hold
count is incremented by one and the method returns immediately.
If the lock is held by another thread then the
current thread becomes disabled for thread scheduling
purposes and lies dormant until the lock has been acquired,
at which time the lock hold count is set to one.
如果锁没有被其他线程持有,则获取锁并返回
立即,将锁的保持数设置为1。
如果当前线程已经持有锁,那么保持数
数值递增1,并立即返回该方法。
如果锁被其他线程持有,那么
当前线程将被禁用,无法进行线程调度
目的,并在获得锁之前处于休眠状态。
这时,锁住次数被设置为1。
dormant 蛰伏, 其实就是阻塞。
获取同步锁。 如果
/
public void lock() {
sync.lock();
}
/**
Acquires the lock unless the current thread is
{@linkplain Thread#interrupt interrupted}.
Acquires the lock if it is not held by another thread and returns
immediately, setting the lock hold count to one.
If the current thread already holds this lock then the hold count
is incremented by one and the method returns immediately.
If the lock is held by another thread then the
current thread becomes disabled for thread scheduling
purposes and lies dormant until one of two things happens:
If the lock is acquired by the current thread then the lock hold
count is set to one.
If the current thread:
In this implementation, as this method is an explicit
interruption point, preference is given to responding to the
interrupt over normal or reentrant acquisition of the lock.
获得锁,除非当前线程是
{@linkplain Thread#interrupt interrupted}。
如果锁没有被其他线程持有,则获取该锁并返回
立即,将锁的保持数设置为1。
如果当前线程已经持有此锁,那么保持数
增量为1,并且该方法立即返回。
如果锁被其他线程持有,那么
当前线程被禁用,无法进行线程调度
目的,并处于休眠状态,直到发生两种情况之一。
如果锁是由当前线程获得的,那么锁保持
count被设置为1。
如果当前线程。
在本实施例中,由于该方法是一个显式的
中断点,优先考虑回应
中断超过正常或重入式获取锁。
通过www.DeepL.com/Translator(免费版)翻译
@throws InterruptedException if the current thread is interrupted
/
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
/**
Acquires the lock only if it is not held by another thread at the time
of invocation.
Acquires the lock if it is not held by another thread and
returns immediately with the value {@code true}, setting the
lock hold count to one. Even when this lock has been set to use a
fair ordering policy, a call to {@code tryLock()} will
immediately acquire the lock if it is available, whether or not
other threads are currently waiting for the lock.
This "barging" behavior can be useful in certain
circumstances, even though it breaks fairness. If you want to honor
the fairness setting for this lock, then use
{@link #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }
which is almost equivalent (it also detects interruption).
If the current thread already holds this lock then the hold
count is incremented by one and the method returns {@code true}.
If the lock is held by another thread then this method will return
immediately with the value {@code false}.
@return {@code true} if the lock was free and was acquired by the
current thread, or the lock was already held by the current
thread; and {@code false} otherwise
/
只有在当时没有被其他线程持有的情况下,才会获得锁 的调用。
如果锁不是由另一个线程持有,那么就会获取该锁。
立即返回值{@code true},设置为
锁定保持数为1。即使该锁已被设置为使用一个
公平订购策略,调用{@code tryLock()} 将
如果有锁,则立即购买,无论是否有锁
其他线程目前正在等待锁定。
这种"barging"行为在某些情况下是有用的。
情况下,即使打破了公平。如果你想尊重
此锁的公平性设置,然后使用
{@link #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }
几乎是等效的(它也会检测到中断)。
如果当前的线程已经持有这个锁,那么持有的
count被递增1,并且该方法将返回{@code true}。
如果锁被另一个线程持有,那么这个方法将返回{@code true}。
值 {@code false}立即返回 {@code false}。
如果该锁是自由的,并且是通过
锁定,或者当前线程已经被当前的
线程; 和 {@code false}否则
public boolean tryLock() { 浅尝而止 浅尝辄止
return sync.nonfairTryAcquire(1);
}
/**
Acquires the lock if it is not held by another thread within the given
waiting time and the current thread has not been
{@linkplain Thread#interrupt interrupted}.
Acquires the lock if it is not held by another thread and returns
immediately with the value {@code true}, setting the lock hold count
to one. If this lock has been set to use a fair ordering policy then
an available lock will not be acquired if any other threads
are waiting for the lock. This is in contrast to the {@link #tryLock()}
method. If you want a timed {@code tryLock} that does permit barging on
a fair lock then combine the timed and un-timed forms together:
{@code
if (lock.tryLock() ||
lock.tryLock(timeout, unit)) {
...
}}
If the current thread
already holds this lock then the hold count is incremented by one and
the method returns {@code true}.
If the lock is held by another thread then the
current thread becomes disabled for thread scheduling
purposes and lies dormant until one of three things happens:
If the lock is acquired then the value {@code true} is returned and
the lock hold count is set to one.
If the current thread:
If the specified waiting time elapses then the value {@code false}
is returned. If the time is less than or equal to zero, the method
will not wait at all.
In this implementation, as this method is an explicit
interruption point, preference is given to responding to the
interrupt over normal or reentrant acquisition of the lock, and
over reporting the elapse of the waiting time.
@param timeout the time to wait for the lock
@param unit the time unit of the timeout argument
@return {@code true} if the lock was free and was acquired by the
current thread, or the lock was already held by the current
thread; and {@code false} if the waiting time elapsed before
the lock could be acquired
@throws InterruptedException if the current thread is interrupted
@throws NullPointerException if the time unit is null
/
public boolean tryLock(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}
/**
Attempts to release this lock.
If the current thread is the holder of this lock then the hold
count is decremented. If the hold count is now zero then the lock
is released. If the current thread is not the holder of this
lock then {@link IllegalMonitorStateException} is thrown.
如果当前的线程是该锁的持有者,那么该锁的持有者就会被持有
数被递减。 如果现在的保持数为零,那么锁的数量就会减少。
被释放。 如果当前线程的持有人不是这个
锁,然后{@link IllegalMonitorStateException}被抛出。
@throws IllegalMonitorStateException if the current thread does not
hold this lock
/
public void unlock() {
sync.release(1);
}
/**
Returns a {@link Condition} instance for use with this
{@link Lock} instance.
The returned {@link Condition} instance supports the same
usages as do the {@link Object} monitor methods ({@link
Object#wait() wait}, {@link Object#notify notify}, and {@link
Object#notifyAll notifyAll}) when used with the built-in
monitor lock.
返回的{@link条件}实例支持相同的
使用方法({@link对象}监控方法({@link
Object#wait() wait}, {@link Object#notify notify notify}, 和 {@link
Object#notifyAll notifyAll})与内置的
监视器锁。
/**
Queries the number of holds on this lock by the current thread.
A thread has a hold on a lock for each lock action that is not
matched by an unlock action.
The hold count information is typically only used for testing and
debugging purposes. For example, if a certain section of code should
not be entered with the lock already held then we can assert that
fact:
查询当前线程对该锁的持有数量。
一个线程对一个锁的每一个锁动作都有一个持有量,而不是
匹配的解锁操作。
持有数信息通常只用于测试和调试的目的。例如,如果某一段代码应该是 不在锁已被锁住的情况下进入,那么我们可以断言下面的事实:
{@code
class X {
ReentrantLock lock = new ReentrantLock();
// ...
public void m() {
assert lock.getHoldCount() == 0;
lock.lock();
try {
// ... method body
} finally {
lock.unlock();
}
}
}}
/**
Queries if this lock is held by the current thread.
Analogous to the {@link Thread#holdsLock(Object)} method for
built-in monitor locks, this method is typically used for
debugging and testing. For example, a method that should only be
called while a lock is held can assert that this is the case:
{@code
class X {
ReentrantLock lock = new ReentrantLock();
// ...
public void m() {
assert lock.isHeldByCurrentThread();
// ... method body
}
}}
It can also be used to ensure that a reentrant lock is used
in a non-reentrant manner, for example:
{@code
class X {
ReentrantLock lock = new ReentrantLock();
// ...
public void m() {
assert !lock.isHeldByCurrentThread();
lock.lock();
try {
// ... method body
} finally {
lock.unlock();
}
}
}}
/**
Queries if this lock is held by any thread. This method is
designed for use in monitoring of the system state,
not for synchronization control.
查询该锁是否被任何线程持有。该方法是用于监测系统状态。不用于同步控制。
@return {@code true} if any thread holds this lock and
{@code false} otherwise
/
public boolean isLocked() {
return sync.isLocked();
}
/**
Returns {@code true} if this lock has fairness set true.
@return {@code true} if this lock has fairness set true
/
public final boolean isFair() {
return sync instanceof FairSync;
}
/**
Returns the thread that currently owns this lock, or
{@code null} if not owned. When this method is called by a
thread that is not the owner, the return value reflects a
best-effort approximation of current lock status. For example,
the owner may be momentarily {@code null} even if there are
threads trying to acquire the lock but have not yet done so.
This method is designed to facilitate construction of
subclasses that provide more extensive lock monitoring
facilities.
返回当前拥有此锁的线程,或
{@code null},如果不拥有。当这个方法被一个
的线程,返回值反映了一个非所有者的
当前锁定状态的最佳近似值。例如:
即使有,所有者可能暂时{@code null},即使有
试图获得锁的线程,但还没有这样做。
这种方法的目的是为了方便构建
子类,提供更广泛的锁监控
设施。
momentarily 刹那间
@return the owner, or {@code null} if not owned
/
protected Thread getOwner() {
return sync.getOwner();
}
/**
Queries whether any threads are waiting to acquire this lock. Note that
because cancellations may occur at any time, a {@code true}
return does not guarantee that any other thread will ever
acquire this lock. This method is designed primarily for use in
monitoring of the system state.
查询是否有线程在等待获取此锁。需要注意的是因为随时都可能发生取消,所以{@@code true}。
返回并不保证任何其他的线程都会获得此锁。 这种方法主要用于 系统状态的监测。
@return {@code true} if there may be other threads waiting to
acquire the lock
/
public final boolean hasQueuedThreads() {
return sync.hasQueuedThreads();
}
/**
Queries whether the given thread is waiting to acquire this
lock. Note that because cancellations may occur at any time, a
{@code true} return does not guarantee that this thread
will ever acquire this lock. This method is designed primarily for use
in monitoring of the system state.
查询给定的线程是否正在等待获取这个
锁定。请注意,由于随时都可能发生取消,所以
{@code true}返回并不保证这个线程的
将获得此锁。 这种方法主要是为了使用
在监测系统状态方面。
@param thread the thread
@return {@code true} if the given thread is queued waiting for this lock
@throws NullPointerException if the thread is null
/
public final boolean hasQueuedThread(Thread thread) { 方法名取得并不好~!
return sync.isQueued(thread); 查询给定的线程是否正在等待获取这个
锁定,即看它释放已经入队
}
/**
Returns an estimate of the number of threads waiting to
acquire this lock. The value is only an estimate because the number of
threads may change dynamically while this method traverses
internal data structures. This method is designed for use in
monitoring of the system state, not for synchronization
control.
又是监测系统
@return the estimated number of threads waiting for this lock
/
public final int getQueueLength() { 获取同步状态等待的线程的个数
return sync.getQueueLength();
}
/**
Returns a collection containing threads that may be waiting to
acquire this lock. Because the actual set of threads may change
dynamically while constructing this result, the returned
collection is only a best-effort estimate. The elements of the
returned collection are in no particular order. This method is
designed to facilitate construction of subclasses that provide
more extensive monitoring facilities.
又是监测系统
@return the collection of threads
/
protected Collection
return sync.getQueuedThreads();
}
/**
Queries whether any threads are waiting on the given condition
associated with this lock. Note that because timeouts and
interrupts may occur at any time, a {@code true} return does
not guarantee that a future {@code signal} will awaken any
threads. This method is designed primarily for use in
monitoring of the system state.
查询是否有线程在等待给定的条件。
与此锁相关联。请注意,由于超时和
中断可能在任何时候发生,{@code true}返回的是
不能保证未来的{@code信号}会唤醒任何的
螺纹。 这种方法主要用于
系统状态的监测。
@param condition the condition
@return {@code true} if there are any waiting threads
@throws IllegalMonitorStateException if this lock is not held
@throws IllegalArgumentException if the given condition is
not associated with this lock
@throws NullPointerException if the condition is null
/
public boolean hasWaiters(Condition condition) {
if (condition == null)
throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
}
/**
Returns an estimate of the number of threads waiting on the
given condition associated with this lock. Note that because
timeouts and interrupts may occur at any time, the estimate
serves only as an upper bound on the actual number of waiters.
This method is designed for use in monitoring of the system
state, not for synchronization control.
又是监测系统
@param condition the condition
@return the estimated number of waiting threads
@throws IllegalMonitorStateException if this lock is not held
@throws IllegalArgumentException if the given condition is
not associated with this lock
@throws NullPointerException if the condition is null
/
public int getWaitQueueLength(Condition condition) { 获取条件等待的线程的个数
if (condition == null)
throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
}
/**
Returns a collection containing those threads that may be
waiting on the given condition associated with this lock.
Because the actual set of threads may change dynamically while
constructing this result, the returned collection is only a
best-effort estimate. The elements of the returned collection
are in no particular order. This method is designed to
facilitate construction of subclasses that provide more
extensive condition monitoring facilities.
@param condition the condition
@return the collection of threads
@throws IllegalMonitorStateException if this lock is not held
@throws IllegalArgumentException if the given condition is
not associated with this lock
@throws NullPointerException if the condition is null
/
protected Collection
if (condition == null)
throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
}
/**
Returns a string identifying this lock, as well as its lock state.
The state, in brackets, includes either the String {@code "Unlocked"}
or the String {@code "Locked by"} followed by the
{@linkplain Thread#getName name} of the owning thread.
@return a string identifying this lock, as well as its lock state
/
public String toString() {
Thread o = sync.getOwner();
return super.toString() + ((o == null) ?
"[Unlocked]" :
"[Locked by thread " + o.getName() + "]");
}
}