Java中是否存在一种快速失败的同步方式?

Der*_*ang 4 java concurrency

假设我有一个这样的代码片段

synchronized(obj) {
    do something;
}
Run Code Online (Sandbox Code Playgroud)

如果obj已被某个其他线程锁定,则此代码将等待直到obj释放,之后它将尝试获取锁定.

但我想知道如果无法立即获得锁定,是否有任何方法可以跳过代码块?

换句话说,有没有办法检测对象是否已被锁定?

更新:

感谢您提及Lock界面,但这需要程序遵守相同的合同,即,它们都引用Lock对象而不是synchronized关键字.

我想知道是否有内置的检查锁定状态的方法?

谢谢.

Ste*_*n C 16

你不能使用原始对象锁来做到这一点.

(好吧,在你可以考虑使用的一些JVM sun.misc.Unsafe上做这个,但这是一个非常糟糕的主意.你可能会发现你的编译器,类加载器或安全沙箱阻止你使用UnsafeAPI ......应该这样做.没有任何东西,这个API不被称为"不安全"!)

java.util.concurrent.locks.LockAPI有一个方法,可以让你试图获得一个锁不阻塞.具体而言,该tryLock()方法尝试获取锁定并false在锁定正在使用时立即返回.

(还有其他更高级别的并发类可以用作ersatz锁......但这不是它们的设计目的.)


换句话说,有没有办法检测对象是否已被锁定?

实际上,这有点不同......并不完全有用.当然,你可以(假设)测试是否持有锁.(并且有些Semaphore类支持这一点.)但这并不意味着你可以保证能够在不阻塞的情况下获得锁定.如果你做出(不正确的)假设,你已经在你的代码中引入了一个Heisenbug.


我想知道是否有内置的检查锁定状态的方法?

[假设你指的是原始锁...]

不,没有.至少,不在运行的应用程序本身内.(调试代理可以执行此操作,但应用程序与其JVM的调试代理进行通信是不切实际的.)

如果你想/需要做这种事情,你就没有真正的选择,不涉及改变你的应用程序的锁定机制.它就是这样儿的.