Shared Reentrant Lock

Description

Fully distributed locks that are globally synchronous, meaning at any snapshot in time no two clients think they hold the same lock.

Participating Classes

  • InterProcessMutex

Usage

Create an InterProcessMutex

public InterProcessMutex(CuratorFramework client,
                         String path)
Parameters:
client - client
path - the path to lock

General Usage

To acquire the lock, use one of the acquire methods:

public void acquire()
Acquire the mutex - blocking until it's available. Note: the same thread can call acquire
re-entrantly. Each call to acquire must be balanced by a call to release()
public boolean acquire(long time,
                       TimeUnit unit)
Acquire the mutex - blocks until it's available or the given time expires. Note: the same thread can
call acquire re-entrantly. Each call to acquire that returns true must be balanced by a call to release()

Parameters:
time - time to wait
unit - time unit
Returns:
true if the mutex was acquired, false if not

To release the mutex, call:

public void release()
Perform one release of the mutex if the calling thread is the same thread that acquired it. If the
thread had made multiple calls to acquire, the mutex will still be held when this method returns.

NOTE: A InterProcessMutex instance is reusable. i.e. don't create a new instance every time. Re-use a single instance.

Revoking

InterProcessMutex supports a cooperative revocation mechanism as described on the ZooKeeper recipes wiki.

To make a mutex revocable, call:

public void makeRevocable(RevocationListener<T> listener)
Make the lock revocable. Your listener will get called when another process/thread wants you to release the lock. Revocation is cooperative.
Parameters:
listener - the listener

To ask for a lock to revoke/release, use the static method in the Revoker class:

public static void attemptRevoke(CuratorFramework client,
                                 String path)
                         throws Exception
Utility to mark a lock for revocation. Assuming that the lock has been registered
with a RevocationListener, it will get called and the lock should be released. Note,
however, that revocation is cooperative.
Parameters:
client - the client
path - the path of the lock - usually from something like InterProcessMutex.getParticipantNodes()

Error Handling

It is strongly recommended that you add a ConnectionStateListener and watch for SUSPENDED and LOST state changes. If a SUSPENDED state is reported you cannot be certain that you still hold the lock unless you subsequently receive a RECONNECTED state. If a LOST state is reported it is certain that you no longer hold the lock.