Java中是否有一种快速失败的同步方式?
我认为使用“快速失败”来描述您在这里尝试做的事情是一个糟糕的术语选择。快速失败意味着不立即获取锁是失败或应用程序错误;cf 快速失败迭代器会抛出未经检查的 CCME。这不是一般的锁提供的语义模型,或者特别是这里。更好的术语是“非阻塞”
此外,由于无法获取锁而静默跳过代码块是一种有用的行为,这一点也不清楚。在大多数情况下,应用程序需要知道已采用“跳过”路径。
撇开这些点不谈,你不能使用原始对象锁来做到这一点。
(好的,在某些 JVM 上您可能可以使用它sun.misc.Unsafe
来执行此操作,但这是一个非常糟糕的主意。您可能会发现您的编译器、类加载器或安全沙箱会阻止您使用Unsafe
API ......因为它应该这样做。此外,这个 API 并不是无缘无故被称为“不安全”的!)
该java.util.concurrent.locks.Lock
API 有一个方法允许您尝试在不阻塞的情况下获得锁。具体来说,该tryLock()
方法尝试获取锁并false
在锁正在使用时立即返回。
还有其他更高级别的并发类可以用作 ersatz 锁;例如Semaphore
。
或者换一种说法,有没有办法检测一个对象是否已经被锁定?
实际上,这有点不同……而且也不完全有用。当然,您可以(假设地)测试是否持有锁。(确实有些Lock
类明确支持这一点。)但这并不意味着您可以保证能够在不阻塞的情况下获取锁。如果您做出该(不正确的)假设,则您已在代码中引入了 Heisenbug。
我想知道是否有一种检查锁定状态的内置方法?
[假设您指的是原始锁......]
不,没有。至少,不在正在运行的应用程序本身内。(调试代理可以做到这一点,但应用程序与其 JVM 的调试代理对话是不切实际的。)
如果您想要/需要做这种事情,那么您没有不涉及更改应用程序锁定机制的实际选择。它就是这样儿的。