org.apache.commons.transaction.locking
Class GenericLockManager

java.lang.Object
  extended by org.apache.commons.transaction.locking.GenericLockManager
All Implemented Interfaces:
LockManager, LockManager2
Direct Known Subclasses:
ReadWriteLockManager

public class GenericLockManager
extends java.lang.Object
implements LockManager, LockManager2

Manager for GenericLocks on resources. This implementation includes

Version:
$Revision$

Field Summary
protected  long checkThreshhold
           
static long DEFAULT_CHECK_THRESHHOLD
           
static long DEFAULT_TIMEOUT
           
protected  java.util.Map effectiveGlobalTimeouts
          Maps onwerId to global effective time outs (i.e.
protected  java.util.Map globalLocks
          Maps resourceId to lock.
protected  java.util.Map globalOwners
          Maps onwerId to locks it (partially) owns.
protected  long globalTimeoutMSecs
           
protected  LoggerFacade logger
           
protected  int maxLockLevel
           
protected  java.util.Set timedOutOwners
           
 
Constructor Summary
GenericLockManager(int maxLockLevel, LoggerFacade logger)
           
GenericLockManager(int maxLockLevel, LoggerFacade logger, long timeoutMSecs)
           
GenericLockManager(int maxLockLevel, LoggerFacade logger, long timeoutMSecs, long checkThreshholdMSecs)
          Creates a new generic lock manager.
 
Method Summary
protected  void addOwner(java.lang.Object ownerId, GenericLock lock)
           
 MultiLevelLock atomicGetOrCreateLock(java.lang.Object resourceId)
          Either gets an existing lock on the specified resource or creates one if none exists.
 boolean checkLock(java.lang.Object ownerId, java.lang.Object resourceId, int targetLockLevel, boolean reentrant)
          Determines if a lock could be acquire without actually acquiring it.
protected  GenericLock createLock(java.lang.Object resourceId)
           
protected  void doLock(GenericLock lock, java.lang.Object ownerId, java.lang.Object resourceId, int targetLockLevel, int compatibility, boolean preferred, long timeoutMSecs)
           
 java.util.Set getAll(java.lang.Object ownerId)
          Gets all locks (partially) held by an owner.
 int getLevel(java.lang.Object ownerId, java.lang.Object resourceId)
          Gets the lock level held by certain owner on a certain resource.
 MultiLevelLock getLock(java.lang.Object resourceId)
          Gets an existing lock on the specified resource.
 java.util.Collection getLocks()
          Gets all locks as orignials, no copies.
protected  long getNextGlobalConflictTimeout(java.util.Set conflicts)
           
 boolean hasLock(java.lang.Object ownerId, java.lang.Object resourceId, int lockLevel)
          Determines if a lock is owner by an owner.
 void lock(java.lang.Object ownerId, java.lang.Object resourceId, int targetLockLevel, boolean reentrant)
          Tries to acquire a lock on a resource.
 void lock(java.lang.Object ownerId, java.lang.Object resourceId, int targetLockLevel, boolean reentrant, long timeoutMSecs)
          Tries to acquire a lock on a resource.
 void lock(java.lang.Object ownerId, java.lang.Object resourceId, int targetLockLevel, int compatibility, boolean preferred, long timeoutMSecs)
          Most flexible way to acquire a lock on a resource.
 boolean release(java.lang.Object ownerId, java.lang.Object resourceId)
          Releases all locks for a certain resource held by a certain owner.
 void releaseAll(java.lang.Object ownerId)
          Releases all locks (partially) held by an owner.
protected  void releaseAllNoTimeOutReset(java.lang.Object ownerId)
           
protected  boolean releaseTimedOutOwners()
           
 void removeLock(MultiLevelLock lock)
          Removes the specified lock from the associated resource.
protected  void removeOwner(java.lang.Object ownerId, GenericLock lock)
           
 void startGlobalTimeout(java.lang.Object ownerId, long timeoutMSecs)
          Starts a global timeout for an owner.
protected  boolean timeOut(java.lang.Object ownerId)
           
protected  void timeoutCheck(java.lang.Object ownerId)
           
 java.lang.String toString()
           
 boolean tryLock(java.lang.Object ownerId, java.lang.Object resourceId, int targetLockLevel, boolean reentrant)
          Tries to acquire a lock on a resource.
protected  boolean wouldDeadlock(java.lang.Object ownerId, java.util.Set path)
          Checks if an owner is deadlocked.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

DEFAULT_TIMEOUT

public static final long DEFAULT_TIMEOUT
See Also:
Constant Field Values

DEFAULT_CHECK_THRESHHOLD

public static final long DEFAULT_CHECK_THRESHHOLD
See Also:
Constant Field Values

globalOwners

protected java.util.Map globalOwners
Maps onwerId to locks it (partially) owns.


globalLocks

protected java.util.Map globalLocks
Maps resourceId to lock.


effectiveGlobalTimeouts

protected java.util.Map effectiveGlobalTimeouts
Maps onwerId to global effective time outs (i.e. the time the lock will time out).


timedOutOwners

protected java.util.Set timedOutOwners

maxLockLevel

protected int maxLockLevel

logger

protected LoggerFacade logger

globalTimeoutMSecs

protected long globalTimeoutMSecs

checkThreshhold

protected long checkThreshhold
Constructor Detail

GenericLockManager

public GenericLockManager(int maxLockLevel,
                          LoggerFacade logger,
                          long timeoutMSecs,
                          long checkThreshholdMSecs)
                   throws java.lang.IllegalArgumentException
Creates a new generic lock manager.

Parameters:
maxLockLevel - highest allowed lock level as described in GenericLock 's class intro
logger - generic logger used for all kind of debug logging
timeoutMSecs - specifies the maximum time to wait for a lock in milliseconds
checkThreshholdMSecs - specifies a special wait threshhold before deadlock and timeout detection come into play or -1 switch it off and check for directly
Throws:
java.lang.IllegalArgumentException - if maxLockLevel is less than 1
Since:
1.1

GenericLockManager

public GenericLockManager(int maxLockLevel,
                          LoggerFacade logger,
                          long timeoutMSecs)
                   throws java.lang.IllegalArgumentException
Throws:
java.lang.IllegalArgumentException

GenericLockManager

public GenericLockManager(int maxLockLevel,
                          LoggerFacade logger)
                   throws java.lang.IllegalArgumentException
Throws:
java.lang.IllegalArgumentException
Method Detail

startGlobalTimeout

public void startGlobalTimeout(java.lang.Object ownerId,
                               long timeoutMSecs)
Description copied from interface: LockManager2
Starts a global timeout for an owner. This is especially usefull, when the owner is a transaction. After a global timeout occurs all of the owner's lock will be released and the owner will not be allowed to access any locks before before calling LockManager2.releaseAll(Object).

Specified by:
startGlobalTimeout in interface LockManager2
Parameters:
ownerId - a unique id identifying the entity that wants to acquire this lock
timeoutMSecs - specifies the global timeout in milliseconds
Since:
1.1
See Also:
LockManager2.startGlobalTimeout(Object, long)

tryLock

public boolean tryLock(java.lang.Object ownerId,
                       java.lang.Object resourceId,
                       int targetLockLevel,
                       boolean reentrant)
Description copied from interface: LockManager2
Tries to acquire a lock on a resource.

This method does not block, but immediatly returns. If a lock is not available false will be returned.

Specified by:
tryLock in interface LockManager2
Parameters:
ownerId - a unique id identifying the entity that wants to acquire this lock
resourceId - the resource to get the level for
targetLockLevel - the lock level to acquire
reentrant - true if this request shall not be influenced by other locks held by the same owner
Returns:
true if the lock has been acquired, false otherwise
Since:
1.1
See Also:
LockManager2.tryLock(Object, Object, int, boolean)

checkLock

public boolean checkLock(java.lang.Object ownerId,
                         java.lang.Object resourceId,
                         int targetLockLevel,
                         boolean reentrant)
Description copied from interface: LockManager2
Determines if a lock could be acquire without actually acquiring it.

This method does not block, but immediatly returns.

Specified by:
checkLock in interface LockManager2
Parameters:
ownerId - a unique id identifying the entity that wants to check this lock
resourceId - the resource to get the level for
targetLockLevel - the lock level to check
reentrant - true if this request shall not be influenced by other locks held by the same owner
Returns:
true if the lock could be acquired, false otherwise
Since:
1.1
See Also:
LockManager2.checkLock(Object, Object, int, boolean)

hasLock

public boolean hasLock(java.lang.Object ownerId,
                       java.lang.Object resourceId,
                       int lockLevel)
Description copied from interface: LockManager2
Determines if a lock is owner by an owner.

Specified by:
hasLock in interface LockManager2
Parameters:
ownerId - a unique id identifying the entity that wants to check this lock
resourceId - the resource to get the level for
lockLevel - the lock level to check
Returns:
true if the owner has the lock, false otherwise
Since:
1.1
See Also:
LockManager2.hasLock(Object, Object, int)

lock

public void lock(java.lang.Object ownerId,
                 java.lang.Object resourceId,
                 int targetLockLevel,
                 boolean reentrant)
          throws LockException
Description copied from interface: LockManager2
Tries to acquire a lock on a resource.

This method blocks and waits for the lock in case it is not avaiable. If there is a timeout or a deadlock or the thread is interrupted a LockException is thrown.

Specified by:
lock in interface LockManager2
Parameters:
ownerId - a unique id identifying the entity that wants to acquire this lock
resourceId - the resource to get the level for
targetLockLevel - the lock level to acquire
reentrant - true if this request shall not be blocked by other locks held by the same owner
Throws:
LockException - will be thrown when the lock can not be acquired
Since:
1.1
See Also:
LockManager2.lock(Object, Object, int, boolean)

lock

public void lock(java.lang.Object ownerId,
                 java.lang.Object resourceId,
                 int targetLockLevel,
                 boolean reentrant,
                 long timeoutMSecs)
          throws LockException
Description copied from interface: LockManager2
Tries to acquire a lock on a resource.

This method blocks and waits for the lock in case it is not avaiable. If there is a timeout or a deadlock or the thread is interrupted a LockException is thrown.

Specified by:
lock in interface LockManager2
Parameters:
ownerId - a unique id identifying the entity that wants to acquire this lock
resourceId - the resource to get the level for
targetLockLevel - the lock level to acquire
reentrant - true if this request shall not be blocked by other locks held by the same owner
timeoutMSecs - specifies the maximum wait time in milliseconds
Throws:
LockException - will be thrown when the lock can not be acquired
Since:
1.1
See Also:
LockManager2.lock(Object, Object, int, boolean, long)

lock

public void lock(java.lang.Object ownerId,
                 java.lang.Object resourceId,
                 int targetLockLevel,
                 int compatibility,
                 boolean preferred,
                 long timeoutMSecs)
          throws LockException
Description copied from interface: LockManager2
Most flexible way to acquire a lock on a resource.

This method blocks and waits for the lock in case it is not avaiable. If there is a timeout or a deadlock or the thread is interrupted a LockException is thrown.

Specified by:
lock in interface LockManager2
Parameters:
ownerId - a unique id identifying the entity that wants to acquire this lock
resourceId - the resource to get the level for
targetLockLevel - the lock level to acquire
compatibility - MultiLevelLock2.COMPATIBILITY_NONEif no additional compatibility is desired (same as reentrant set to false) , MultiLevelLock2.COMPATIBILITY_REENTRANTif lock level by the same owner shall not affect compatibility (same as reentrant set to true), or MultiLevelLock2.COMPATIBILITY_SUPPORTif lock levels that are the same as the desired shall not affect compatibility, or finally MultiLevelLock2.COMPATIBILITY_REENTRANT_AND_SUPPORTwhich is a combination of reentrant and support
preferred - in case this lock request is incompatible with existing ones and we wait, it shall be granted before other waiting requests that are not preferred
timeoutMSecs - specifies the maximum wait time in milliseconds
Throws:
LockException - will be thrown when the lock can not be acquired
Since:
1.1
See Also:
LockManager2.lock(Object, Object, int, int, boolean, long)

doLock

protected void doLock(GenericLock lock,
                      java.lang.Object ownerId,
                      java.lang.Object resourceId,
                      int targetLockLevel,
                      int compatibility,
                      boolean preferred,
                      long timeoutMSecs)

getLevel

public int getLevel(java.lang.Object ownerId,
                    java.lang.Object resourceId)
Description copied from interface: LockManager2
Gets the lock level held by certain owner on a certain resource.

Specified by:
getLevel in interface LockManager2
Parameters:
ownerId - the id of the owner of the lock
resourceId - the resource to get the level for
Since:
1.1
See Also:
LockManager2.getLevel(Object, Object)

release

public boolean release(java.lang.Object ownerId,
                       java.lang.Object resourceId)
Description copied from interface: LockManager2
Releases all locks for a certain resource held by a certain owner.

Specified by:
release in interface LockManager2
Parameters:
ownerId - the id of the owner of the lock
resourceId - the resource to releases the lock for
Returns:
true if the lock actually was released, false in case there was no lock held by the owner
Since:
1.1
See Also:
LockManager2.release(Object, Object)

releaseAll

public void releaseAll(java.lang.Object ownerId)
Description copied from interface: LockManager2
Releases all locks (partially) held by an owner.

Specified by:
releaseAll in interface LockManager2
Parameters:
ownerId - the id of the owner
Since:
1.1
See Also:
LockManager2.releaseAll(Object)

releaseAllNoTimeOutReset

protected void releaseAllNoTimeOutReset(java.lang.Object ownerId)

getAll

public java.util.Set getAll(java.lang.Object ownerId)
Description copied from interface: LockManager2
Gets all locks (partially) held by an owner.

Specified by:
getAll in interface LockManager2
Parameters:
ownerId - the id of the owner
Returns:
all locks held by ownerId
Since:
1.1
See Also:
LockManager2.getAll(Object)

addOwner

protected void addOwner(java.lang.Object ownerId,
                        GenericLock lock)

removeOwner

protected void removeOwner(java.lang.Object ownerId,
                           GenericLock lock)

wouldDeadlock

protected boolean wouldDeadlock(java.lang.Object ownerId,
                                java.util.Set path)
Checks if an owner is deadlocked.

We traverse the tree recursively formed by owners, locks held by them and then again owners waiting for the locks. If there is a cycle in one of the paths from the root to a leaf we have a deadlock.

A more detailed discussion on deadlocks and definitions and how to detect them can be found in this nice article .
Caution: This computation can be very expensive with many owners and locks. Worst (unlikely) case is exponential.

Parameters:
ownerId - the owner to check for being deadlocked
path - initially should be called with an empty set
Returns:
true if the owner is deadlocked, false otherwise

releaseTimedOutOwners

protected boolean releaseTimedOutOwners()

timeOut

protected boolean timeOut(java.lang.Object ownerId)

getNextGlobalConflictTimeout

protected long getNextGlobalConflictTimeout(java.util.Set conflicts)

getLock

public MultiLevelLock getLock(java.lang.Object resourceId)
Description copied from interface: LockManager
Gets an existing lock on the specified resource. If none exists it returns null.

Specified by:
getLock in interface LockManager
Specified by:
getLock in interface LockManager2
Parameters:
resourceId - the resource to get the lock for
Returns:
the lock on the specified resource

atomicGetOrCreateLock

public MultiLevelLock atomicGetOrCreateLock(java.lang.Object resourceId)
Description copied from interface: LockManager
Either gets an existing lock on the specified resource or creates one if none exists. This methods guarantees to do this atomically.

Specified by:
atomicGetOrCreateLock in interface LockManager
Parameters:
resourceId - the resource to get or create the lock on
Returns:
the lock for the specified resource

removeLock

public void removeLock(MultiLevelLock lock)
Description copied from interface: LockManager
Removes the specified lock from the associated resource.

Specified by:
removeLock in interface LockManager
Specified by:
removeLock in interface LockManager2
Parameters:
lock - the lock to be removed

getLocks

public java.util.Collection getLocks()
Gets all locks as orignials, no copies.

Returns:
collection holding all locks.

toString

public java.lang.String toString()
Overrides:
toString in class java.lang.Object

createLock

protected GenericLock createLock(java.lang.Object resourceId)

timeoutCheck

protected void timeoutCheck(java.lang.Object ownerId)
                     throws LockException
Throws:
LockException


Copyright ? 2004 The Apache Software Foundation. All Rights Reserved.