public abstract class AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer implements Serializable
int
值来表示状态。
子类必须定义改变此状态的受保护方法,以及根据该对象被获取或释放来定义该状态的含义。
给定这些,这个类中的其他方法执行所有排队和阻塞机制。
子类可以保持其他状态字段,但只以原子方式更新int
使用方法操纵值getState()
, setState(int)
和compareAndSetState(int, int)
被跟踪相对于同步。
子类应定义为非公共内部助手类,用于实现其封闭类的同步属性。 AbstractQueuedSynchronizer
类不实现任何同步接口。 相反,它定义了一些方法,如acquireInterruptibly(int)
,可以通过具体的锁和相关同步器来调用适当履行其公共方法。
此类支持默认独占模式和共享模式。 当以独占模式获取时,尝试通过其他线程获取不能成功。 多线程获取的共享模式可能(但不需要)成功。 除了在机械意义上,这个类不理解这些差异,当共享模式获取成功时,下一个等待线程(如果存在)也必须确定它是否也可以获取。 在不同模式下等待的线程共享相同的FIFO队列。 通常,实现子类只支持这些模式之一,但是两者都可以在ReadWriteLock
中发挥作用 。 仅支持独占或仅共享模式的子类不需要定义支持未使用模式的方法。
这个类定义的嵌套AbstractQueuedSynchronizer.ConditionObject
可用于作为一类Condition
由子类支持独占模式用于该方法的实施isHeldExclusively()
份报告是否同步排他相对于保持在当前线程,方法release(int)
与当前调用getState()
值完全释放此目的,和acquire(int)
,给定此保存的状态值,最终将此对象恢复到其先前获取的状态。 AbstractQueuedSynchronizer
方法将创建此类条件,因此如果不能满足此约束,请勿使用该约束。 AbstractQueuedSynchronizer.ConditionObject
的行为当然取决于其同步器实现的语义。
该类为内部队列提供检查,检测和监控方法,以及条件对象的类似方法。 这些可以根据需要导出到类中,使用AbstractQueuedSynchronizer
进行同步机制。
此类的序列化仅存储底层原子整数维持状态,因此反序列化对象具有空线程队列。 需要可序列化的典型子类将定义一个readObject
方法,可以将其恢复为readObject
时的已知初始状态。
使用这个类用作同步的基础上,重新定义以下方法,如适用,通过检查和/或修改使用所述同步状态getState()
, setState(int)
和/或compareAndSetState(int, int)
:
UnsupportedOperationException
。
这些方法的实现必须是线程安全的,通常应该是短的而不是阻止的。
定义这些方法是唯一支持使用此类的方法。
所有其他方法都被声明为final
,因为它们不能独立变化。
您还可以找到来自继承的方法AbstractOwnableSynchronizer
有用跟踪线程拥有独家同步的。 我们鼓励您使用它们 - 这样可以使监控和诊断工具帮助用户确定哪些线程持有锁定。
即使这个类基于内部FIFO队列,它也不会自动执行FIFO采集策略。 排他同步的核心形式如下:
Acquire:
while (!tryAcquire(arg)) {
enqueue thread if it is not already queued;
possibly block current thread;
}
Release:
if (tryRelease(arg))
unblock the first queued thread;
(共享模式类似,但可能包含级联信号。)
因为在采集检查入队之前调用,所以新获取的线程可能闯入其他被阻塞和排队的。 但是,如果需要,您可以通过内部调用一个或多个检查方法来定义tryAcquire
和/或tryAcquireShared
来禁用驳船,从而提供一个合理的 FIFO采购订单。 特别地,最公平同步器可以定义tryAcquire
返回false
如果hasQueuedPredecessors()
(具体地设计成由公平同步器中使用的方法)返回true
。 其他变化是可能的。
吞吐量和可扩展性通常对于默认的驳船(也称为贪心 , 放弃和车队避免 )战略来说是最高的。 虽然这不能保证是公平的或无饥饿的,但较早排队的线程在稍后排队的线程之前被允许重新侦听,并且每次重新提供对于传入线程成功的机会。 此外,虽然获取在通常意义上不“旋转”,但是在阻止之前它们可以执行多个tryAcquire
tryAcquire与其他计算的交互。 当独占同步只是简单地持有时,这样可以提供旋转的大部分好处,而没有大部分负债。 如果需要,您可以通过以前通过“快速路径”检查获取方法的调用进行扩充,可能预先检查hasContended()
和/或hasQueuedThreads()
,以便只有在同步器可能不被竞争的情况下才能进行。
该类为同步提供了一个高效和可扩展的基础,部分原因是可以依靠int
状态,获取和释放参数以及内部FIFO等待队列的同步器的使用范围。 当这不足够时,您可以使用atomic
类,您自己的自定义Queue
类和LockSupport
类阻止支持从较低级别构建同步器。
这是一个不可重入互斥锁类,它使用零值来表示解锁状态,一个表示锁定状态。 虽然不可重入锁不严格要求记录当前的所有者线程,但是这样做无论如何使得使用更容易监视。 它还支持条件并公开其中一种仪器方法:
class Mutex implements Lock, java.io.Serializable { // Our internal helper class private static class Sync extends AbstractQueuedSynchronizer { // Reports whether in locked state protected boolean isHeldExclusively() { return getState() == 1; } // Acquires the lock if state is zero public boolean tryAcquire(int acquires) { assert acquires == 1; // Otherwise unused if (compareAndSetState(0, 1)) { setExclusiveOwnerThread(Thread.currentThread()); return true; } return false; } // Releases the lock by setting state to zero protected boolean tryRelease(int releases) { assert releases == 1; // Otherwise unused if (getState() == 0) throw new IllegalMonitorStateException(); setExclusiveOwnerThread(null); setState(0); return true; } // Provides a Condition Condition newCondition() { return new ConditionObject(); } // Deserializes properly private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException { s.defaultReadObject(); setState(0); // reset to unlocked state } } // The sync object does all the hard work. We just forward to it. private final Sync sync = new Sync(); public void lock() { sync.acquire(1); } public boolean tryLock() { return sync.tryAcquire(1); } public void unlock() { sync.release(1); } public Condition newCondition() { return sync.newCondition(); } public boolean isLocked() { return sync.isHeldExclusively(); } public boolean hasQueuedThreads() { return sync.hasQueuedThreads(); } public void lockInterruptibly() throws InterruptedException { sync.acquireInterruptibly(1); } public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException { return sync.tryAcquireNanos(1, unit.toNanos(timeout)); } }
这是一个类似CountDownLatch
的闩锁类,只是它只需要一个signal
才能触发。 因为锁存器是非排他的,它使用shared
获取和释放方法。
class BooleanLatch { private static class Sync extends AbstractQueuedSynchronizer { boolean isSignalled() { return getState() != 0; } protected int tryAcquireShared(int ignore) { return isSignalled() ? 1 : -1; } protected boolean tryReleaseShared(int ignore) { setState(1); return true; } } private final Sync sync = new Sync(); public boolean isSignalled() { return sync.isSignalled(); } public void signal() { sync.releaseShared(1); } public void await() throws InterruptedException { sync.acquireSharedInterruptibly(1); } }
Modifier and Type | Class and Description |
---|---|
class |
AbstractQueuedSynchronizer.ConditionObject
Condition实现 AbstractQueuedSynchronizer 作为基础Lock 实施。
|
Modifier | Constructor and Description |
---|---|
protected |
AbstractQueuedSynchronizer()
创建一个初始同步状态为零的新的
AbstractQueuedSynchronizer 实例。
|
Modifier and Type | Method and Description |
---|---|
void |
acquire(int arg)
以独占模式获取,忽略中断。
|
void |
acquireInterruptibly(int arg)
以独占方式获得,如果中断,中止。
|
void |
acquireShared(int arg)
以共享模式获取,忽略中断。
|
void |
acquireSharedInterruptibly(int arg)
以共享方式获取,如果中断,中止。
|
protected boolean |
compareAndSetState(int expect, int update)
如果当前状态值等于期望值,则将同步状态原子地设置为给定的更新值。
|
Collection<Thread> |
getExclusiveQueuedThreads()
返回一个包含可能正在等待以独占模式获取的线程的集合。
|
Thread |
getFirstQueuedThread()
返回队列中第一个(等待时间最长的)线程,或
null 如果没有线程正在排队。
|
Collection<Thread> |
getQueuedThreads()
返回一个包含可能正在等待获取的线程的集合。
|
int |
getQueueLength()
返回等待获取的线程数的估计。
|
Collection<Thread> |
getSharedQueuedThreads()
返回包含可能正在等待在共享模式下获取的线程的集合。
|
protected int |
getState()
返回同步状态的当前值。
|
Collection<Thread> |
getWaitingThreads(AbstractQueuedSynchronizer.ConditionObject condition)
返回一个集合,其中包含可能正在等待与此同步器相关联的给定条件的线程。
|
int |
getWaitQueueLength(AbstractQueuedSynchronizer.ConditionObject condition)
返回等待与此同步器相关联的给定条件的线程数量的估计。
|
boolean |
hasContended()
查询任何线程是否有争取获取此同步器;
那就是收购方法是否被阻止。
|
boolean |
hasQueuedPredecessors()
查询任何线程是否等待获取比当前线程更长的时间。
|
boolean |
hasQueuedThreads()
查询任何线程是否等待获取。
|
boolean |
hasWaiters(AbstractQueuedSynchronizer.ConditionObject condition)
查询任何线程是否等待与此同步器相关联的给定条件。
|
protected boolean |
isHeldExclusively()
返回
true 如果同步仅针对当前(调用)线程进行保存。
|
boolean |
isQueued(Thread thread)
如果给定的线程当前排队,则返回true。
|
boolean |
owns(AbstractQueuedSynchronizer.ConditionObject condition)
查询给定的ConditionObject是否将此同步器用作其锁。
|
boolean |
release(int arg)
以专属模式发布。
|
boolean |
releaseShared(int arg)
以共享模式发布。
|
protected void |
setState(int newState)
设置同步状态的值。
|
String |
toString()
返回一个标识此同步器的字符串及其状态。
|
protected boolean |
tryAcquire(int arg)
尝试以独占模式获取。
|
boolean |
tryAcquireNanos(int arg, long nanosTimeout)
尝试以独占模式获取,如果中断则中止,如果给定的超时时间失败。
|
protected int |
tryAcquireShared(int arg)
尝试以共享模式获取。
|
boolean |
tryAcquireSharedNanos(int arg, long nanosTimeout)
尝试以共享模式获取,如果中断则中止,如果给定的时间超过,则失败。
|
protected boolean |
tryRelease(int arg)
尝试设置状态以独占模式反映版本。
|
protected boolean |
tryReleaseShared(int arg)
尝试将状态设置为以共享模式反映发布。
|
getExclusiveOwnerThread, setExclusiveOwnerThread
protected AbstractQueuedSynchronizer()
AbstractQueuedSynchronizer
实例。
protected final int getState()
volatile
读取的记忆语义。
protected final void setState(int newState)
volatile
写的内存语义。
newState
- 新的状态值
protected final boolean compareAndSetState(int expect, int update)
volatile
读写的记忆语义。
expect
- 期望值
update
- 新的价值
true
如果成功。
False return表示实际值不等于预期值。
protected boolean tryAcquire(int arg)
该方法总是由执行获取的线程调用。 如果此方法报告失败,则获取方法可能将线程排队(如果尚未排队),直到被其他线程释放为止。 这可以用于实现方法Lock.tryLock()
。
默认实现会抛出UnsupportedOperationException
。
arg
- 获取的论据。
该值始终是传递给获取方法的值,或者是进入条件等待时保存的值。
该值否则无法解释,可以代表您喜欢的任何内容。
true
如果成功。
一旦成功,这个对象就被收购了。
IllegalMonitorStateException
- 如果获取将该同步器置于非法状态。
必须以一致的方式抛出此异常,以使同步正常工作。
UnsupportedOperationException
- 如果不支持独占模式
protected boolean tryRelease(int arg)
arg
- 释放参数。
该值始终是传递给release方法的值,或者进入条件等待时的当前状态值。
该值否则无法解释,可以代表您喜欢的任何内容。
true
如果此对象现在处于完全释放状态,那么任何等待的线程都可能尝试获取;
和false
其他。
IllegalMonitorStateException
- 如果释放将使此同步器处于非法状态。
必须以一致的方式抛出此异常,以使同步正常工作。
UnsupportedOperationException
- 如果不支持独占模式
protected int tryAcquireShared(int arg)
该方法总是由执行获取的线程调用。 如果此方法报告失败,则获取方法可能将线程排队(如果尚未排队),直到被其他线程释放为止。
默认实现抛出UnsupportedOperationException
。
arg
- 获取的论据。
该值始终是传递给获取方法的值,或者是进入条件等待时保存的值。
该值否则无法解释,可以代表您喜欢的任何内容。
IllegalMonitorStateException
- 如果获取将该同步器置于非法状态。
必须以一致的方式抛出此异常,以使同步正常工作。
UnsupportedOperationException
- 如果不支持共享模式
protected boolean tryReleaseShared(int arg)
arg
- 释放参数。
该值始终是传递给release方法的值,或者进入条件等待时的当前状态值。
该值否则无法解释,可以代表您喜欢的任何内容。
true
如果这种共享模式的释放可能允许等待获取(共享或排他)成功;
false
false
IllegalMonitorStateException
- 如果释放将使此同步器处于非法状态。
必须以一致的方式抛出此异常,以使同步正常工作。
UnsupportedOperationException
- 如果不支持共享模式
protected boolean isHeldExclusively()
true
。
每次调用不等待AbstractQueuedSynchronizer.ConditionObject
方法时都会调用此方法。
(等待方法调用release(int)
。 )
默认实现抛出UnsupportedOperationException
。 此方法仅在AbstractQueuedSynchronizer.ConditionObject
方法内部调用,因此如果不使用条件,则不需要定义该方法。
true
如果同步是唯一的;
false
否则
UnsupportedOperationException
- 如果不支持条件
public final void acquire(int arg)
tryAcquire(int)
实现,成功返回。
否则线程排队,可能会重复阻塞和解除阻塞,直到成功才调用tryAcquire(int)
。
该方法可用于实现方法Lock.lock()
。
arg
- 收购论据。
该值传达到tryAcquire(int)
,否则将无法解释,可以代表您喜欢的任何内容。
public final void acquireInterruptibly(int arg) throws InterruptedException
tryAcquire(int)
,成功返回。
否则线程排队,可能会重复阻塞和解除阻塞,调用tryAcquire(int)
直到成功或线程中断。
该方法可以用于实现方法Lock.lockInterruptibly()
。
arg
- 获取的论据。
这个值传达给tryAcquire(int)
,但是没有被解释,可以代表你喜欢的任何东西。
InterruptedException
- 当前线程是否中断
public final boolean tryAcquireNanos(int arg, long nanosTimeout) throws InterruptedException
tryAcquire(int)
,成功返回。
否则,线程排队,可能会重复阻塞和解除阻塞,调用tryAcquire(int)
直到成功或线程中断或超时。
该方法可用于实现方法Lock.tryLock(long, TimeUnit)
。
arg
- 获取的论据。
该值传达到tryAcquire(int)
,否则无法解释,可以代表您喜欢的任何内容。
nanosTimeout
- 要等待的最大纳秒数
true
如果获得;
false
如果超时
InterruptedException
- 当前线程是否中断
public final boolean release(int arg)
arg
- 释放参数。
这个值被传达到tryRelease(int)
,但是没有被解释,可以代表你喜欢的任何东西。
tryRelease(int)
返回的值
public final void acquireShared(int arg)
tryAcquireShared(int)
,成功返回。
否则线程排队,可能会重复阻塞和解除阻塞,直到成功调用tryAcquireShared(int)
。
arg
- 获取的论据。
该值传达给tryAcquireShared(int)
,否则将被解释,可以代表您喜欢的任何内容。
public final void acquireSharedInterruptibly(int arg) throws InterruptedException
tryAcquireShared(int)
,成功返回。
否则线程排队,可能会重复阻塞和解除阻塞,调用tryAcquireShared(int)
直到成功或线程中断。
arg
- 获取的论据。
该值传达给tryAcquireShared(int)
,否则无法解释,可以代表您喜欢的任何内容。
InterruptedException
- 当前线程是否中断
public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout) throws InterruptedException
tryAcquireShared(int)
,成功返回。
否则,线程排队,可能会重复阻塞和解除阻塞,调用tryAcquireShared(int)
直到成功或线程中断或超时。
arg
- 收购论据。
该值传达到tryAcquireShared(int)
,否则无法解释,可以代表您喜欢的任何内容。
nanosTimeout
- 等待的最大纳秒数
true
如果获得;
false
如果超时
InterruptedException
- 如果当前线程中断
public final boolean releaseShared(int arg)
tryReleaseShared(int)
返回true,则通过解除阻塞一个或多个线程来实现。
arg
- 释放参数。
该值传达给tryReleaseShared(int)
,否则无法解释,可以代表您喜欢的任何内容。
tryReleaseShared(int)
返回的值
public final boolean hasQueuedThreads()
true
, true
返回不能保证任何其他线程将获得。
在这个实现中,这个操作返回恒定的时间。
true
如果可能有其他线程等待获取
public final boolean hasContended()
在这个实现中,这个操作返回恒定的时间。
true
如果有争议
public final Thread getFirstQueuedThread()
null
如果没有线程正在排队。
在这个实现中,这个操作通常在常量时间内返回,但如果其他线程同时修改队列,则可以在争用时迭代。
null
如果没有线程当前排队
public final boolean isQueued(Thread thread)
该实现遍历队列以确定给定线程的存在。
thread
- 线程
true
如果给定的线程在队列上
NullPointerException
- 如果线程为空
public final boolean hasQueuedPredecessors()
调用此方法等同于(但可能更有效):
getFirstQueuedThread() != Thread.currentThread() && hasQueuedThreads()
请注意,由于中断和超时可能会随时发生true
,因此true
返回不能保证其他一些线程将在当前线程之前获取。 同样,由于队列为空,这个方法已经返回false
,因此另一个线程可能会赢得比赛排入队列。
该方法被设计为由一个公平的同步器使用,以避免barging 。 这样一个同步器的tryAcquire(int)
方法应该返回false
,并且它的tryAcquireShared(int)
方法应该返回一个负值,如果这个方法返回true
(除非这是一个可重入的获取)。 例如, tryAcquire
公平,可重入,独占模式同步器的方法可能如下所示:
protected boolean tryAcquire(int arg) { if (isHeldExclusively()) { // A reentrant acquire; increment hold count return true; } else if (hasQueuedPredecessors()) { return false; } else { // try to acquire normally } }
true
如果当前线程之前有一个排队的线程,如果当前线程在队列的头部或队列为空,
false
public final int getQueueLength()
public final Collection<Thread> getQueuedThreads()
public final Collection<Thread> getExclusiveQueuedThreads()
getQueuedThreads()
,除了它只返回那些等待的线程由于独家获取。
public final Collection<Thread> getSharedQueuedThreads()
getQueuedThreads()
,但它仅返回那些等待的线程由于共享获取。
public String toString()
"State ="
接着的当前值getState()
,并且或者"nonempty"
或"empty"
取决于队列是否为空。
public final boolean owns(AbstractQueuedSynchronizer.ConditionObject condition)
condition
- 条件
true
如果拥有
NullPointerException
- 条件为空
public final boolean hasWaiters(AbstractQueuedSynchronizer.ConditionObject condition)
true
返回不能保证未来的signal
将唤醒任何线程。
该方法主要用于监视系统状态。
condition
- 条件
true
如果有任何等待线程
IllegalMonitorStateException
- 如果不保留独占同步
IllegalArgumentException
- 如果给定的条件与此同步器无关
NullPointerException
- 如果条件为空
public final int getWaitQueueLength(AbstractQueuedSynchronizer.ConditionObject condition)
condition
- 条件
IllegalMonitorStateException
- 如果不保留独占同步
IllegalArgumentException
- 如果给定的条件与该同步器没有关联
NullPointerException
- 如果条件为空
public final Collection<Thread> getWaitingThreads(AbstractQueuedSynchronizer.ConditionObject condition)
condition
- 条件
IllegalMonitorStateException
- 如果不保留独占同步
IllegalArgumentException
- 如果给定的条件不与此同步器相关联
NullPointerException
- 如果条件为空