Class ObjectLockManager<O,L>

java.lang.Object
de.aristaflow.adept2.util.locking.ObjectLockManager<O,L>
Type Parameters:
O - The type of the objects to be locked (locked object type).
L - The type of the objects that lock (lock owning type).
Direct Known Subclasses:
OptimisticObjectLockManager, PessimisticObjectLockManager

public abstract class ObjectLockManager<O,L> extends Object
A manager for locking objects with reentrant locks whereas the locks are itself object specific. That is, an object locks another object; the locking objects are managed using a LockCountManager which allows to flexibly change the equality of the locking objects.
The locks are reentrant and read or write locks, that is a locking object (or also some other locking object considered equal) may acquire a lock multiple times (and have to release it multiple times with the same type (read or write)) but all non-equal locking objects will not receive the lock in case of a write lock. A read lock may be acquired by arbitrary other locking objects as long as there is no different locking object waiting to write.
How a lock works depends on the LockCountManager provided to the constructor of this manager. This may treat various objects as equal concerning locks (for instance object hierarchies) or not.

Lock upgrades and downgrades are impossible. When requesting a read lock while having a write the read lock will implicitly be granted as write lock. When releasing such a read lock, this will be implicitly a release of a write lock.

This class only provides the basic means, the real locking, lock creation and synchronisation has to be provided by subclasses. These may also whether they behave optimistically or pessimistically.

Author:
Ulrich Kreher
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    protected final Class<? extends LockCountManager<? super L>>
    The lock count manager implementation which handles the lock counts per lock.
    protected final String
    The type of lock as informal string for user information.
    protected final Logger
    The logger for logging lock acquisitions and releasing - great for debugging purpose.
  • Constructor Summary

    Constructors
    Modifier
    Constructor
    Description
    protected
    ObjectLockManager(Class<? extends LockCountManager<? super L>> lockCountManager, String lockType, Logger logger)
    Creates a new ObjectLockManager with the designated lock count manager providing the "equality" for the designated reentrant locks and of the designated type.
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    getLockForObject(boolean writeLock, L lockingObject, O lockedObject)
    Locks the designated object by the designated locking object.
    final void
    getLockForObject(boolean writeLock, L lockingObject, O lockedObject, long timeout)
    Locks the designated object by the designated locking object.
    protected abstract void
    getLockForObjectReadWriteDirect(boolean writeLock, L lockingObject, O lockedObject, long timeout)
    Cf.
    protected abstract ReentrantLock<L>
    getObjectLock(O lockedObject)
    Gets the lock for the designated object.
    boolean
    hasLock(boolean writeLock, L lockingObject, O lockedObject)
    Checks whether the designated object is locked for reading or writing by the designated locking object.
    boolean
    unlockObject(boolean writeLock, L lockingObject, O lockedObject)
    Unlocks the designated object by the designated locking object.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • lockCountManager

      protected final Class<? extends LockCountManager<? super L>> lockCountManager
      The lock count manager implementation which handles the lock counts per lock.
    • lockType

      protected final String lockType
      The type of lock as informal string for user information.
    • logger

      protected final Logger logger
      The logger for logging lock acquisitions and releasing - great for debugging purpose.
  • Constructor Details

    • ObjectLockManager

      protected ObjectLockManager(Class<? extends LockCountManager<? super L>> lockCountManager, String lockType, Logger logger)
      Creates a new ObjectLockManager with the designated lock count manager providing the "equality" for the designated reentrant locks and of the designated type.
      Parameters:
      lockCountManager - The lock count manager that encapsulates what locking objects are treated as equal when acquiring a lock. The provided class needs an accessible (public) constructor without parameters.
      lockType - The type of locks managed by the created object. This is for user information only.
      logger - The logger for log messages.
  • Method Details

    • getObjectLock

      protected abstract ReentrantLock<L> getObjectLock(O lockedObject)
      Gets the lock for the designated object. This allows subclasses to use their own data structure for lock management.
      Parameters:
      lockedObject - The locked object for which to retrieve the corresponding reentrant lock.
      Returns:
      The reentrant lock for the designated locked object or null in case the designated object is not locked.
    • getLockForObject

      public void getLockForObject(boolean writeLock, L lockingObject, O lockedObject) throws InterruptedException
      Locks the designated object by the designated locking object.

      Calls ObjectLockManager.getLockForObject(writeLock, lockingObject, lockedObject, 0).

      Parameters:
      writeLock - Whether to acquire a write lock.
      lockingObject - The object locking the designated object.
      lockedObject - The object to lock.
      Throws:
      InterruptedException - If the thread is interrupted while waiting for the lock, an InterruptedException will be thrown.
      RuntimeException - If the provided lock count manager can not be instantiated, a RuntimeException will be thrown.
    • getLockForObject

      public final void getLockForObject(boolean writeLock, L lockingObject, O lockedObject, long timeout) throws InterruptedException, TimeoutException
      Locks the designated object by the designated locking object. Since the locks are expected to be short-term this method will wait until the lock can be successfully acquired. The locks are reentrant, that is, it needs to be unlocked for every call to this method and for the right lock type (read or write lock).
      When locking an object for reading while already having the write lock for the object, the lock will be granted as write lock. When releasing such a read lock, a write lock will be released implicitly instead.
      Parameters:
      writeLock - Whether to acquire a write lock.
      lockingObject - The object locking the designated object.
      lockedObject - The object to lock.
      timeout - The time to wait for the lock. A timeout <= 0 means to wait forever (or until the lock is granted).
      Throws:
      InterruptedException - If the thread is interrupted while waiting for the lock, an InterruptedException will be thrown.
      TimeoutException - If the designated timeout elapsed before the lock can be acquired, a TimeoutException will be thrown.
      RuntimeException - If the provided lock or the lock count manager can not be instantiated, a RuntimeException will be thrown.
    • getLockForObjectReadWriteDirect

      protected abstract void getLockForObjectReadWriteDirect(boolean writeLock, L lockingObject, O lockedObject, long timeout) throws InterruptedException, TimeoutException
      Cf. documentation of getLockForObject(boolean, Object, Object, long). Implementors can rely on the first boolean to be set appropriately depending on present locks.
      Parameters:
      writeLock - Whether to acquire a write lock. This will already be adapted to a write lock if required, that is, requesting a read lock while having the write lock already.
      lockingObject - The object locking the designated object.
      lockedObject - The object to lock.
      timeout - The time to wait for the lock. A timeout <= 0 means to wait forever (or until the lock is granted).
      Throws:
      InterruptedException - If the thread is interrupted while waiting for the lock, an InterruptedException will be thrown.
      TimeoutException - If the designated timeout elapsed before the lock can be acquired, a TimeoutException will be thrown.
      RuntimeException - If the provided lock or the lock count manager can not be instantiated, a RuntimeException will be thrown.
    • hasLock

      public boolean hasLock(boolean writeLock, L lockingObject, O lockedObject)
      Checks whether the designated object is locked for reading or writing by the designated locking object.
      Parameters:
      writeLock - Whether the locking object is to be checked for having a write lock on the designated locked object.
      lockingObject - The object to check for having the lock on the designated object.
      lockedObject - The object to check for the lock lock.
      Returns:
      Whether the designated locking object has the designated lock on the designated locked object.
    • unlockObject

      public boolean unlockObject(boolean writeLock, L lockingObject, O lockedObject) throws LockException
      Unlocks the designated object by the designated locking object. The lock will not be released if it is held several times. If the LockException occurs while trying to unlock, the lock will still be held when returning.
      Parameters:
      writeLock - Whether to release the write lock.
      lockingObject - The object unlocking the designated object.
      lockedObject - The object to unlock.
      Returns:
      Whether a notification has been sent when unlocking. This is the same as ReentrantLock.Lock.unlock(Object) and usually only required by subclasses.
      Throws:
      LockException - If the locked object has not locked at all or not by the designated locking object, a LockException will be thrown.