2012-04-21 71 views
4

比方说,我有一个代码片段这样Java中有一种快速同步的同步方式吗?

synchronized(obj) { 
    do something; 
} 

如果obj已经由其他线程锁定,该代码会等到obj发布之后,它会试图获得锁。

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

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

UPDATE:

感谢提Lock接口,但要求节目服从相同的合同,即,它们都指Lock对象,而不是​​关键字。

我不知道是否有内置的方式来检查锁定状态?

谢谢。

+0

如果你想获得你必须遵循相同的合同一切与该对象的工作反正锁做到这一点。 .. – trutheality 2012-04-21 03:41:44

+0

@trutheality好点,谢谢。 – 2012-04-21 08:14:37

+1

如果您可以绑定到Sun JVM,那么还有'sun.misc.Unsafe#tryMonitorEnter(Object)',如下所述:http://www.javaspecialists.eu/archive/Issue194.html – 2012-04-21 10:48:18

回答

13

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

(OK,在某些JVM上,你可以考虑使用sun.misc.Unsafe要做到这一点,但是这是一个非常糟糕的主意。你可能会发现你的编译器,类加载器或安全沙箱阻止你使用Unsafe API ..这个API不会被称为“不安全”)

java.util.concurrent.locks.Lock API有一个方法,允许你尝试获得一个没有阻塞的锁。具体而言,tryLock()方法尝试获取该锁,并在锁正在使用时立即返回false

(有,你可以使用作为代用锁等更高级别的并发类...但是这不是他们设计的。)


或者换一种说法,是有检测对象是否已被锁定的方法?

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


我不知道是否有检查锁定状态的一个内置的方式吗?

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

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

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

0

您可以使用java.util.concurrent.Semaphore中它可以让你更好地控制