As I was using tryLock()
method in one of my project, while using the same the question which is striking mind is that - tryLock()
is said to be non blocking mechanism, how does it manages to get a lock without blocking.
There can be two scenario
synchronized
block/method internally, then the question is, how does it work in multi threaded environmentsynchronized
block/method internally, then the question is, how is it non blockingIn order to find the answer I have checked the below code for tryLock
public boolean tryLock() {
return sync.nonfairTryAcquire(1);
}
And here goes the code for sync.nonfairTryAcquire(1)
which actually gets the work done
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
As it seems that the code for tryLock()
does not use synchronized
anywhere, how does it work in multi threaded environment?
how does it manages to get a lock without blocking?
It doesn't always get the lock. That's the whole point: lock.tryLock()
can fail when lock.lock()
would have blocked the caller.
it does not use synchronized block or function
That would defeat the purpose. The point is not to block for any reason.
I am not familiar with that code, but it looks like the lock actually is acquired (or not) in compareAndSetState(0, acquires)
. Probably there is a Compare and Set hardware instruction somewhere at the heart of it.
FWIW, The AtomicInteger.compareAndSet(...) function does something very similar.