Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a fail-fast way of synchronization in Java?

Let's say I have a code snippet like this

synchronized(obj) {
    do something;
}

If obj was already locked by some other thread, this code will wait until obj released and after that it will try to get the lock.

But I want to know if there is any way to jump over the code block if the lock can not be gained immediately?

Or put it another way, is there a way to detect whether or not an object is already locked ?

UPDATE:

Thanks for mentioning the Lock interface, but that require programs to obey the same contract, i.e, they all refer to a Lock object instead of the synchronized keyword.

I wonder if there is a built-in way of checking the locking status ?

Thanks.

like image 960
Derrick Zhang Avatar asked Dec 05 '22 16:12

Derrick Zhang


1 Answers

Is there a fail-fast way of synchronization in Java?

I think it is a poor choice of terminology to use "fail-fast" to describe what you are trying to do here. Fail-fast implies that not being to acquire a lock instantly is a failure or application error; c.f. fail-fast iterators which throw an unchecked CCME. That's not the semantic model offered by locks in general, or here in particular. A better term would be "non-blocking"

Also, it is not clear that silently skipping a block of code because you can't acquire a lock is useful behavior. In most cases, the application needs to know that the "skip" path has been taken.

These points aside, you can't do it using primitive object locks.

(OK, on some JVMs you might be able to use sun.misc.Unsafe to do this, but that's a really bad idea. You are likely to find that your compiler, class loader or security sandbox stops you from using the Unsafe API ... as it should. Besides, this API is not called "unsafe" for nothing!)

The java.util.concurrent.locks.Lock API has a method that allows you to attempt to gain a lock without blocking. Specifically, the tryLock() method attempts to acquire the lock and immediately returns false if the lock is in use.

There are other higher level concurrency classes that you could use as ersatz locks; e.g. Semaphore.


Or put it another way, is there a way to detect whether or not an object is already locked ?

Actually, that is a bit different ... and not entirely useful either. Sure, you could (hypothetically) test if a lock is being held. (Indeed some Lock classes explicitly support this.) But that doesn't mean that you'd be guaranteed to be able to acquire the lock without blocking. If you make that (incorrect) assumption, you've introduced a Heisenbug into your code.


I wonder if there is a built-in way of checking the locking status ?

[Assuming that you are referring to primitive locks ... ]

No there isn't. At least, not within the running application itself. (A debug agent can do this, but it is not practical for an application to talk to its JVM's debug agent.)

If you want / need to do this kind of thing, you've got no real options that don't involve changing your application's locking mechanism. That's the way it is.

like image 173
Stephen C Avatar answered Dec 14 '22 10:12

Stephen C