StampedLock 类
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
具有三种模式的基于功能的锁,用于控制读/写访问。
[Android.Runtime.Register("java/util/concurrent/locks/StampedLock", ApiSince=24, DoNotGenerateAcw=true)]
public class StampedLock : Java.Lang.Object, IDisposable, Java.Interop.IJavaPeerable, Java.IO.ISerializable
[<Android.Runtime.Register("java/util/concurrent/locks/StampedLock", ApiSince=24, DoNotGenerateAcw=true)>]
type StampedLock = class
inherit Object
interface ISerializable
interface IJavaObject
interface IDisposable
interface IJavaPeerable
- 继承
- 属性
- 实现
注解
具有三种模式的基于功能的锁,用于控制读/写访问。 StampedLock 的状态由版本和模式组成。 锁获取方法返回一个标记,该标记表示和控制与锁定状态相关的访问;这些方法的“try”版本可能改为返回特殊值零,表示获取访问权限失败。 锁释放和转换方法需要标记作为参数,如果它们与锁的状态不匹配,则失败。 这三种模式包括:
<ul>
<li><b>写作。</b> 方法 #writeLock
可能会阻止等待独占访问,并返回可用于方法 #unlockWrite
中以释放锁的标记。 还提供了 的 tryWriteLock
未计时版本和计时版本。 当锁定处于写入模式时,可能不会获取任何读取锁,并且所有乐观读取验证都将失败。
<li><b>Reading.</b> 方法 #readLock
可能会阻止等待非独占访问,并返回可用于方法 #unlockRead
中以释放锁的标记。 还提供了 的 tryReadLock
未计时版本和计时版本。
<li><b>乐观阅读。</b> 方法 #tryOptimisticRead
仅当锁定当前不处于写入模式时,才返回非零标记。 如果自获取给定标记以来未在写入模式下获取锁,则方法 #validate
返回 true。在这种情况下,在最近一次写入锁释放之前的所有操作都发生在调用 之后的操作 tryOptimisticRead
之前。 此模式可被视为读取锁的极弱版本,编写器随时可能将其断开。 对短只读代码段使用乐观读取模式通常会减少争用并提高吞吐量。 但是,它的使用本质上是脆弱的。 乐观读取部分应仅读取字段,并将其保存在局部变量中,供以后在验证后使用。 在乐观读取模式下读取的字段可能非常不一致,因此仅当你熟悉数据表示形式以检查一致性和/或重复调用方法 validate()
时才适用。 例如,首先读取对象或数组引用,然后访问其字段、元素或方法之一时,通常需要执行此类步骤。
</ul>
此类还支持在三种模式下有条件地提供转换的方法。 例如,方法 #tryConvertToWriteLock
尝试“升级”模式,如果 (1) 已处于写入模式 (2) 在阅读模式下,并且没有其他读取器或 (3 个) 处于乐观读取模式且锁可用,则返回有效的写入标记。 这些方法的形式旨在帮助减少在基于重试的设计中出现的一些代码膨胀。
StampedLock 旨在用作线程安全组件开发中的内部实用工具。 它们的使用依赖于对所保护的数据、对象和方法的内部属性的了解。 它们不是可重入的,因此锁定的正文不应调用可能尝试重新获取锁的其他未知方法 (尽管你可以将标记传递给其他方法,这些方法可以使用或转换它) 。 读取锁定模式的使用依赖于无副作用的相关代码部分。 未验证的乐观读取部分不能调用已知容许潜在不一致的方法。 图章使用有限表示形式,并且不是加密安全的 (即,) ,有效的标记可能是可以猜测的。 标记值可以在 (持续运行一年) 后回收。 未使用或验证保留超过此期限的标记可能无法正确验证。 StampedLock 可序列化,但始终反序列化为初始解锁状态,因此它们对远程锁定没有用。
与 类似 java.util.concurrent.Semaphore Semaphore
,但与大多数 Lock
实现不同,StampedLocks 没有所有权的概念。 可以在一个线程中获取的锁释放或在另一个线程中转换。
StampedLock 的计划策略并非一直更喜欢读者而不是编写者,反之亦然。 所有“试用”方法都是尽力而为的,不一定符合任何计划或公平策略。 任何用于获取或转换锁的“try”方法的零返回不携带有关锁状态的任何信息;后续调用可能会成功。
由于它支持跨多个锁模式的协调使用,因此此类不直接实现 Lock
或 ReadWriteLock
接口。 但是,在仅需要关联功能集的应用程序中,可以查看 #asReadLock()
、 #asWriteLock()
或 #asReadWriteLock()
StampedLock。
<b>内存同步。</b> 具有在任何模式下成功锁定效果的方法具有与 em>Lock</em> 操作相同的内存同步效果<,如引用>Java 语言规范</引用>的第 17 <章中所述。 在写入模式下成功解锁的方法具有与 em Unlock/em> 操作相同的内存同步效果<。>< 在乐观读取用法中,在最近写入模式解锁操作之前的操作保证发生在 tryOptimisticRead 之后的操作之前,前提是以后的验证返回 true;否则,无法保证 tryOptimisticRead 和 validate 之间的读取会获得一致的快照。
<b>示例用法。</b> 下面演示了维护简单二维点的类中的一些用法习惯。 示例代码演示了一些 try/catch 约定,尽管此处不严格需要它们,因为它们的正文中不会发生异常。
{@code
class Point {
private double x, y;
private final StampedLock sl = new StampedLock();
// an exclusively locked method
void move(double deltaX, double deltaY) {
long stamp = sl.writeLock();
try {
x += deltaX;
y += deltaY;
} finally {
sl.unlockWrite(stamp);
}
}
// a read-only method
// upgrade from optimistic read to read lock
double distanceFromOrigin() {
long stamp = sl.tryOptimisticRead();
try {
retryHoldingLock: for (;; stamp = sl.readLock()) {
if (stamp == 0L)
continue retryHoldingLock;
// possibly racy reads
double currentX = x;
double currentY = y;
if (!sl.validate(stamp))
continue retryHoldingLock;
return Math.hypot(currentX, currentY);
}
} finally {
if (StampedLock.isReadLockStamp(stamp))
sl.unlockRead(stamp);
}
}
// upgrade from optimistic read to write lock
void moveIfAtOrigin(double newX, double newY) {
long stamp = sl.tryOptimisticRead();
try {
retryHoldingLock: for (;; stamp = sl.writeLock()) {
if (stamp == 0L)
continue retryHoldingLock;
// possibly racy reads
double currentX = x;
double currentY = y;
if (!sl.validate(stamp))
continue retryHoldingLock;
if (currentX != 0.0 || currentY != 0.0)
break;
stamp = sl.tryConvertToWriteLock(stamp);
if (stamp == 0L)
continue retryHoldingLock;
// exclusive access
x = newX;
y = newY;
return;
}
} finally {
if (StampedLock.isWriteLockStamp(stamp))
sl.unlockWrite(stamp);
}
}
// upgrade read lock to write lock
void moveIfAtOrigin2(double newX, double newY) {
long stamp = sl.readLock();
try {
while (x == 0.0 && y == 0.0) {
long ws = sl.tryConvertToWriteLock(stamp);
if (ws != 0L) {
stamp = ws;
x = newX;
y = newY;
break;
}
else {
sl.unlockRead(stamp);
stamp = sl.writeLock();
}
}
} finally {
sl.unlock(stamp);
}
}
}}
在 1.8 中添加。
的 java.util.concurrent.locks.StampedLock
Java 文档。
此页面的部分内容是基于 创建和共享的工作进行的修改,并根据 署名许可中所述的术语使用。
构造函数
StampedLock() |
创建一个新锁,最初处于解锁状态。 |
StampedLock(IntPtr, JniHandleOwnership) |
具有三种模式的基于功能的锁,用于控制读/写访问。 |
属性
Class |
返回此 |
Handle |
基础 Android 实例的句柄。 (继承自 Object) |
IsReadLocked |
|
IsWriteLocked |
|
JniIdentityHashCode |
具有三种模式的基于功能的锁,用于控制读/写访问。 (继承自 Object) |
JniPeerMembers |
具有三种模式的基于功能的锁,用于控制读/写访问。 |
PeerReference |
具有三种模式的基于功能的锁,用于控制读/写访问。 (继承自 Object) |
ReadLockCount |
查询为此锁保留的读取锁数。 |
ThresholdClass |
具有三种模式的基于功能的锁,用于控制读/写访问。 |
ThresholdType |
具有三种模式的基于功能的锁,用于控制读/写访问。 |
方法
AsReadLock() |
返回此 StampedLock 的普通 |
AsReadWriteLock() |
返回 |
AsWriteLock() |
返回此 StampedLock 的普通 |
Clone() |
创建并返回此对象的副本。 (继承自 Object) |
Dispose() |
具有三种模式的基于功能的锁,用于控制读/写访问。 (继承自 Object) |
Dispose(Boolean) |
具有三种模式的基于功能的锁,用于控制读/写访问。 (继承自 Object) |
Equals(Object) |
指示其他某个对象是否“等于”此对象。 (继承自 Object) |
GetHashCode() |
返回对象的哈希代码值。 (继承自 Object) |
IsLockStamp(Int64) |
指示标记是否表示持有锁。 |
IsOptimisticReadStamp(Int64) |
指示标记是否表示成功的乐观读取。 |
IsReadLockStamp(Int64) |
指示标记是否表示以非独占方式持有锁。 |
IsWriteLockStamp(Int64) |
指示标记是否代表以独占方式持有锁。 |
JavaFinalize() |
当垃圾回收确定不再引用对象时,由对象上的垃圾回收器调用。 (继承自 Object) |
Notify() |
唤醒正在等待此对象的监视器的单个线程。 (继承自 Object) |
NotifyAll() |
唤醒正在等待此对象的监视器的所有线程。 (继承自 Object) |
ReadLock() |
非独占获取锁,必要时会阻止,直到可用。 |
ReadLockInterruptibly() |
非独占获取锁,在必要时会阻止,直到可用或当前线程中断。 |
SetHandle(IntPtr, JniHandleOwnership) |
设置 Handle 属性。 (继承自 Object) |
ToArray<T>() |
具有三种模式的基于功能的锁,用于控制读/写访问。 (继承自 Object) |
ToString() |
返回对象的字符串表示形式。 (继承自 Object) |
TryConvertToOptimisticRead(Int64) |
如果锁定状态与给定的标记匹配,则原子上,如果该标记表示持有锁,则释放它并返回观察标记。 |
TryConvertToReadLock(Int64) |
如果锁定状态与给定的标记匹配,则以原子方式执行以下操作之一。 |
TryConvertToWriteLock(Int64) |
如果锁定状态与给定的标记匹配,则以原子方式执行以下操作之一。 |
TryOptimisticRead() |
返回稍后可以验证的标记;如果独占锁定,则返回零。 |
TryReadLock() |
如果锁立即可用,则非独占获取锁。 |
TryReadLock(Int64, TimeUnit) |
如果锁在给定时间内可用且当前线程未中断,则非独占获取锁。 |
TryUnlockRead() |
如果已保留读取锁,则释放一个保留,而无需标记值。 |
TryUnlockWrite() |
如果保留写锁,则释放该锁,而无需标记值。 |
TryWriteLock() |
如果锁立即可用,则以独占方式获取锁。 |
TryWriteLock(Int64, TimeUnit) |
如果锁在给定时间内可用且当前线程未中断,则以独占方式获取锁。 |
Unlock(Int64) |
如果锁定状态与给定的标记匹配,则释放锁的相应模式。 |
UnlockRead(Int64) |
如果锁定状态与给定的标记匹配,则释放非独占锁。 |
UnlockWrite(Int64) |
如果锁定状态与给定的标记匹配,则释放独占锁。 |
UnregisterFromRuntime() |
具有三种模式的基于功能的锁,用于控制读/写访问。 (继承自 Object) |
Validate(Int64) |
如果自颁发给定标记以来尚未以独占方式获取锁,则返回 true。 |
Wait() |
导致当前线程等待,直到它被唤醒,通常是通过 em <通知/em> 或 <em>interrupted</em>。<> (继承自 Object) |
Wait(Int64) |
导致当前线程等待,直到它被唤醒,通常是通过 em <通知/em> 或 <em>interrupted</em>,或直到经过一定数量的实时。<> (继承自 Object) |
Wait(Int64, Int32) |
导致当前线程等待,直到它被唤醒,通常是通过 em <通知/em> 或 <em>interrupted</em>,或直到经过一定数量的实时。<> (继承自 Object) |
WriteLock() |
以独占方式获取锁,并在必要时阻止,直到可用。 |
WriteLockInterruptibly() |
以独占方式获取锁,并在必要时阻止,直到可用或当前线程中断。 |
显式接口实现
IJavaPeerable.Disposed() |
具有三种模式的基于功能的锁,用于控制读/写访问。 (继承自 Object) |
IJavaPeerable.DisposeUnlessReferenced() |
具有三种模式的基于功能的锁,用于控制读/写访问。 (继承自 Object) |
IJavaPeerable.Finalized() |
具有三种模式的基于功能的锁,用于控制读/写访问。 (继承自 Object) |
IJavaPeerable.JniManagedPeerState |
具有三种模式的基于功能的锁,用于控制读/写访问。 (继承自 Object) |
IJavaPeerable.SetJniIdentityHashCode(Int32) |
具有三种模式的基于功能的锁,用于控制读/写访问。 (继承自 Object) |
IJavaPeerable.SetJniManagedPeerState(JniManagedPeerStates) |
具有三种模式的基于功能的锁,用于控制读/写访问。 (继承自 Object) |
IJavaPeerable.SetPeerReference(JniObjectReference) |
具有三种模式的基于功能的锁,用于控制读/写访问。 (继承自 Object) |
扩展方法
JavaCast<TResult>(IJavaObject) |
执行 Android 运行时检查的类型转换。 |
JavaCast<TResult>(IJavaObject) |
具有三种模式的基于功能的锁,用于控制读/写访问。 |
GetJniTypeName(IJavaPeerable) |
具有三种模式的基于功能的锁,用于控制读/写访问。 |