public class RaftFencedLockProxy extends ClientProxy implements FencedLock
FencedLock APInameINVALID_FENCE| Constructor and Description |
|---|
RaftFencedLockProxy(ClientContext context,
RaftGroupId groupId,
String proxyName,
String objectName) |
| Modifier and Type | Method and Description |
|---|---|
long |
getFence()
Returns the fencing token if the lock is held by the current thread.
|
CPGroupId |
getGroupId()
Returns id of the CP group that runs this
FencedLock instance |
int |
getLockCount()
Returns the reentrant lock count if the lock is held by any thread
in the cluster.
|
boolean |
isLocked()
Returns whether this lock is locked or not.
|
boolean |
isLockedByCurrentThread()
Returns whether the lock is held by the current thread or not.
|
void |
lock()
Acquires the lock.
|
long |
lockAndGetFence()
Acquires the lock and returns the fencing token assigned to the current
thread for this lock acquire.
|
void |
lockInterruptibly()
Acquires the lock unless the current thread is
interrupted.
|
Condition |
newCondition()
NOT IMPLEMENTED.
|
void |
onDestroy()
Called before proxy is destroyed.
|
protected void |
postDestroy()
Called after proxy is destroyed.
|
boolean |
tryLock()
Acquires the lock if it is available or already held by the current
thread at the time of invocation & the acquire limit is not exceeded,
and immediately returns with the value
true. |
boolean |
tryLock(long time,
TimeUnit unit)
Acquires the lock if it is free within the given waiting time,
or already held by the current thread.
|
long |
tryLockAndGetFence()
Acquires the lock only if it is free or already held by the current
thread at the time of invocation & the acquire limit is not exceeded,
and returns the fencing token assigned to the current thread for this
lock acquire.
|
long |
tryLockAndGetFence(long time,
TimeUnit unit)
Acquires the lock if it is free within the given waiting time,
or already held by the current thread at the time of invocation &
the acquire limit is not exceeded, and returns the fencing token
assigned to the current thread for this lock acquire.
|
void |
unlock()
Releases the lock if the lock is currently held by the current thread.
|
deregisterListener, destroy, destroyLocally, destroyRemotely, equals, getClient, getConnectedServerVersion, getContext, getDistributedObjectName, getId, getName, getPartitionKey, getSerializationService, getServiceName, hashCode, invoke, invoke, invokeOnAddress, invokeOnPartition, invokeOnPartitionInterruptibly, onInitialize, onShutdown, preDestroy, registerListener, setContext, toData, toObjectclone, finalize, getClass, notify, notifyAll, toString, wait, wait, waitdestroy, getName, getPartitionKey, getServiceNamepublic RaftFencedLockProxy(ClientContext context, RaftGroupId groupId, String proxyName, String objectName)
public void lock()
FencedLock
When the caller already holds the lock and the current lock() call is
reentrant, the call can fail with
LockAcquireLimitReachedException if the lock acquire limit is
already reached. Please see FencedLockConfig for more
information.
If the lock is not available then the current thread becomes disabled for thread scheduling purposes and lies dormant until the lock has been acquired.
Consider the following scenario:
FencedLock lock = ...;
lock.lock();
// JVM of the caller thread hits a long pause
// and its CP session is closed on the CP group.
lock.lock();
In this scenario, a thread acquires the lock, then its JVM instance
encounters a long pause, which is longer than
CPSubsystemConfig.getSessionTimeToLiveSeconds(). In this case,
its CP session will be closed on the corresponding CP group because
it could not commit session heartbeats in the meantime. After the JVM
instance wakes up again, the same thread attempts to acquire the lock
reentrantly. In this case, the second lock() call fails by throwing
LockOwnershipLostException which extends
IllegalMonitorStateException. If the caller wants to deal with
its session loss by taking some custom actions, it can handle the thrown
LockOwnershipLostException instance. Otherwise, it can treat it
as a regular IllegalMonitorStateException.lock in interface FencedLocklock in interface Lockpublic void lockInterruptibly()
throws InterruptedException
FencedLock
When the caller already holds the lock and the current lock() call is
reentrant, the call can fail with
LockAcquireLimitReachedException if the lock acquire limit is
already reached. Please see FencedLockConfig for more
information.
If the lock is not available then the current thread becomes disabled for thread scheduling purposes and lies dormant until the lock has been acquired. Interruption may not be possible after the lock request arrives to the CP group, if the proxy does not attempt to retry its lock request because of a failure in the system.
Please note that even if InterruptedException is thrown,
the lock may be acquired on the CP group.
When InterruptedException is thrown, the current thread's
interrupted status is cleared.
Consider the following scenario:
FencedLock lock = ...;
lock.lockInterruptibly();
// JVM of the caller thread hits a long pause
// and its CP session is closed on the CP group.
lock.lockInterruptibly();
In this scenario, a thread acquires the lock, then its JVM instance
encounters a long pause, which is longer than
CPSubsystemConfig.getSessionTimeToLiveSeconds(). In this case,
its CP session will be closed on the corresponding CP group because
it could not commit session heartbeats in the meantime. After the JVM
instance wakes up again, the same thread attempts to acquire the lock
reentrantly. In this case, the second lock() call fails by throwing
LockOwnershipLostException which extends
IllegalMonitorStateException. If the caller wants to deal with
its session loss by taking some custom actions, it can handle the thrown
LockOwnershipLostException instance. Otherwise, it can treat it
as a regular IllegalMonitorStateException.lockInterruptibly in interface FencedLocklockInterruptibly in interface LockInterruptedException - if the current thread is interrupted while
acquiring the lock.public long lockAndGetFence()
FencedLockLockAcquireLimitReachedException if the lock acquire limit is
already reached. Please see FencedLockConfig for more
information.
If the lock is not available then the current thread becomes disabled for thread scheduling purposes and lies dormant until the lock has been acquired.
This is a convenience method for the following pattern:
FencedLock lock = ...;
lock.lock();
return lock.getFence();
Consider the following scenario where the lock is free initially:
FencedLock lock = ...; // the lock is free
lock.lockAndGetFence();
// JVM of the caller thread hits a long pause
// and its CP session is closed on the CP group.
lock.lockAndGetFence();
In this scenario, a thread acquires the lock, then its JVM instance
encounters a long pause, which is longer than
CPSubsystemConfig.getSessionTimeToLiveSeconds(). In this case,
its CP session will be closed on the corresponding CP group because
it could not commit session heartbeats in the meantime. After the JVM
instance wakes up again, the same thread attempts to acquire the lock
reentrantly. In this case, the second lock() call fails by throwing
LockOwnershipLostException which extends
IllegalMonitorStateException. If the caller wants to deal with
its session loss by taking some custom actions, it can handle the thrown
LockOwnershipLostException instance. Otherwise, it can treat it
as a regular IllegalMonitorStateException.
Fencing tokens are monotonic numbers that are incremented each time the lock switches from the free state to the acquired state. They are simply used for ordering lock holders. A lock holder can pass its fencing to the shared resource to fence off previous lock holders. When this resource receives an operation, it can validate the fencing token in the operation.
Consider the following scenario where the lock is free initially:
FencedLock lock = ...; // the lock is free
long fence1 = lock.lockAndGetFence(); // (1)
long fence2 = lock.lockAndGetFence(); // (2)
assert fence1 == fence2;
lock.unlock();
lock.unlock();
long fence3 = lock.lockAndGetFence(); // (3)
assert fence3 > fence1;
In this scenario, the lock is acquired by a thread in the cluster. Then,
the same thread reentrantly acquires the lock again. The fencing token
returned from the second acquire is equal to the one returned from the
first acquire, because of reentrancy. After the second acquire, the lock
is released 2 times, hence becomes free. There is a third lock acquire
here, which returns a new fencing token. Because this last lock acquire
is not reentrant, its fencing token is guaranteed to be larger than the
previous tokens, independent of the thread that has acquired the lock.lockAndGetFence in interface FencedLockpublic boolean tryLock()
FencedLocktrue. If the lock is not
available, then this method immediately returns with the value
false. When the call is reentrant, it can return false
if the lock acquire limit is exceeded. Please see
FencedLockConfig for more information.
A typical usage idiom for this method would be:
FencedLock lock = ...;
if (lock.tryLock()) {
try {
// manipulate protected state
} finally {
lock.unlock();
}
} else {
// perform alternative actions
}
This usage ensures that the lock is unlocked if it was acquired,
and doesn't try to unlock if the lock was not acquired.tryLock in interface FencedLocktryLock in interface Locktrue if the lock was acquired and
false otherwisepublic long tryLockAndGetFence()
FencedLockFencedLock.INVALID_FENCE that represents a failed lock attempt.
Please see FencedLockConfig for more information.
This is a convenience method for the following pattern:
FencedLock lock = ...;
if (lock.tryLock()) {
return lock.getFence();
} else {
return FencedLock.INVALID_FENCE;
}
Consider the following scenario where the lock is free initially:
FencedLock lock = ...; // the lock is free
lock.tryLockAndGetFence();
// JVM of the caller thread hits a long pause
// and its CP session is closed on the CP group.
lock.tryLockAndGetFence();
In this scenario, a thread acquires the lock, then its JVM instance
encounters a long pause, which is longer than
CPSubsystemConfig.getSessionTimeToLiveSeconds(). In this case,
its CP session will be closed on the corresponding CP group because
it could not commit session heartbeats in the meantime. After the JVM
instance wakes up again, the same thread attempts to acquire the lock
reentrantly. In this case, the second lock() call fails by throwing
LockOwnershipLostException which extends
IllegalMonitorStateException. If the caller wants to deal with
its session loss by taking some custom actions, it can handle the thrown
LockOwnershipLostException instance. Otherwise, it can treat it
as a regular IllegalMonitorStateException.
Fencing tokens are monotonic numbers that are incremented each time the lock switches from the free state to the acquired state. They are simply used for ordering lock holders. A lock holder can pass its fencing to the shared resource to fence off previous lock holders. When this resource receives an operation, it can validate the fencing token in the operation.
Consider the following scenario where the lock is free initially:
FencedLock lock = ...; // the lock is free
long fence1 = lock.tryLockAndGetFence(); // (1)
long fence2 = lock.tryLockAndGetFence(); // (2)
assert fence1 == fence2;
lock.unlock();
lock.unlock();
long fence3 = lock.tryLockAndGetFence(); // (3)
assert fence3 > fence1;
In this scenario, the lock is acquired by a thread in the cluster. Then,
the same thread reentrantly acquires the lock again. The fencing token
returned from the second acquire is equal to the one returned from the
first acquire, because of reentrancy. After the second acquire, the lock
is released 2 times, hence becomes free. There is a third lock acquire
here, which returns a new fencing token. Because this last lock acquire
is not reentrant, its fencing token is guaranteed to be larger than the
previous tokens, independent of the thread that has acquired the lock.tryLockAndGetFence in interface FencedLockFencedLock.INVALID_FENCE otherwisepublic boolean tryLock(long time,
TimeUnit unit)
FencedLock
If the lock is available, this method returns immediately with the value
true. When the call is reentrant, it immediately returns
true if the lock acquire limit is not exceeded. Otherwise,
it returns false on the reentrant lock attempt if the acquire
limit is exceeded. Please see FencedLockConfig for more
information.
If the lock is not available then the current thread becomes disabled for thread scheduling purposes and lies dormant until the lock is acquired by the current thread or the specified waiting time elapses.
If the lock is acquired, then the value true is returned.
If the specified waiting time elapses, then the value false
is returned. If the time is less than or equal to zero, the method does
not wait at all.
tryLock in interface FencedLocktryLock in interface Locktime - the maximum time to wait for the lockunit - the time unit of the time argumenttrue if the lock was acquired and false
if the waiting time elapsed before the lock was acquiredpublic long tryLockAndGetFence(long time,
TimeUnit unit)
FencedLockFencedLock.INVALID_FENCE that represents a failed lock attempt.
Please see FencedLockConfig for more information.
If the lock is not available then the current thread becomes disabled for thread scheduling purposes and lies dormant until the lock is acquired by the current thread or the specified waiting time elapses.
If the specified waiting time elapses, then FencedLock.INVALID_FENCE
is returned. If the time is less than or equal to zero, the method does
not wait at all.
This is a convenience method for the following pattern:
FencedLock lock = ...;
if (lock.tryLock(time, unit)) {
return lock.getFence();
} else {
return FencedLock.INVALID_FENCE;
}
Consider the following scenario where the lock is free initially:
FencedLock lock = ...; // the lock is free
lock.tryLockAndGetFence(time, unit);
// JVM of the caller thread hits a long pause and its CP session
is closed on the CP group.
lock.tryLockAndGetFence(time, unit);
In this scenario, a thread acquires the lock, then its JVM instance
encounters a long pause, which is longer than
CPSubsystemConfig.getSessionTimeToLiveSeconds(). In this case,
its CP session will be closed on the corresponding CP group because
it could not commit session heartbeats in the meantime. After the JVM
instance wakes up again, the same thread attempts to acquire the lock
reentrantly. In this case, the second lock() call fails by throwing
LockOwnershipLostException which extends
IllegalMonitorStateException. If the caller wants to deal with
its session loss by taking some custom actions, it can handle the thrown
LockOwnershipLostException instance. Otherwise, it can treat it
as a regular IllegalMonitorStateException.
Fencing tokens are monotonic numbers that are incremented each time the lock switches from the free state to the acquired state. They are simply used for ordering lock holders. A lock holder can pass its fencing to the shared resource to fence off previous lock holders. When this resource receives an operation, it can validate the fencing token in the operation.
Consider the following scenario where the lock is free initially:
FencedLock lock = ...; // the lock is free
long fence1 = lock.tryLockAndGetFence(time, unit); // (1)
long fence2 = lock.tryLockAndGetFence(time, unit); // (2)
assert fence1 == fence2;
lock.unlock();
lock.unlock();
long fence3 = lock.tryLockAndGetFence(time, unit); // (3)
assert fence3 > fence1;
In this scenario, the lock is acquired by a thread in the cluster. Then,
the same thread reentrantly acquires the lock again. The fencing token
returned from the second acquire is equal to the one returned from the
first acquire, because of reentrancy. After the second acquire, the lock
is released 2 times, hence becomes free. There is a third lock acquire
here, which returns a new fencing token. Because this last lock acquire
is not reentrant, its fencing token is guaranteed to be larger than the
previous tokens, independent of the thread that has acquired the lock.tryLockAndGetFence in interface FencedLocktime - the maximum time to wait for the lockunit - the time unit of the time argumentFencedLock.INVALID_FENCE otherwisepublic void unlock()
FencedLockunlock in interface FencedLockunlock in interface Lockpublic long getFence()
FencedLockFencing tokens are monotonic numbers that are incremented each time the lock switches from the free state to the acquired state. They are simply used for ordering lock holders. A lock holder can pass its fencing to the shared resource to fence off previous lock holders. When this resource receives an operation, it can validate the fencing token in the operation.
getFence in interface FencedLockpublic boolean isLocked()
FencedLockisLocked in interface FencedLocktrue if this lock is locked by any thread
in the cluster, false otherwise.public boolean isLockedByCurrentThread()
FencedLockisLockedByCurrentThread in interface FencedLocktrue if the lock is held by the current thread or not,
false otherwise.public int getLockCount()
FencedLockgetLockCount in interface FencedLockpublic CPGroupId getGroupId()
FencedLockFencedLock instancegetGroupId in interface FencedLockFencedLock instancepublic Condition newCondition()
FencedLockUnsupportedOperationException.
May the force be the one who dares to implement
a linearizable distributed Condition :)
newCondition in interface FencedLocknewCondition in interface Lockpublic void onDestroy()
ClientProxyonDestroy in class ClientProxyprotected void postDestroy()
ClientProxypostDestroy in class ClientProxyCopyright © 2019 Hazelcast, Inc.. All Rights Reserved.