public class GenericLock extends Object implements MultiLevelLock2
The idea is to have an ascending number of lock levels ranging from
0 to maxLockLevel as specified in
GenericLock(Object, int, LoggerFacade): the higher the lock level
the stronger and more restrictive the lock. To determine which lock may
coexist with other locks you have to imagine matching pairs of lock levels.
For each pair both parts allow for all lock levels less than or equal to the
matching other part. Pairs are composed by the lowest and highest level not
yet part of a pair and successively applying this method until no lock level
is left. For an even amount of levels each level is part of exactly one pair.
For an odd amount the middle level is paired with itself. The highst lock
level may coexist with the lowest one (0) which by
definition means NO LOCK. This implies that you will have to
specify at least one other lock level and thus set maxLockLevel
to at least 1.
Although this may sound complicated, in practice this is quite simple. Let us imagine you have three lock levels:
0:NO LOCK (always needed by the
implementation of this lock)
1:SHARED
2:EXCLUSIVE
maxLockLevel to
2. Now, there are two pairs of levels
NO LOCK with EXCLUSIVE
SHARED with SHARED
NO LOCK
everything less or equal to EXCLUSIVE is allowed - which means
every other lock level. On the other side EXCLUSIVE allows
exacly for NO LOCK- which means nothing else. In conclusion,
SHARED allows for SHARED or NO
LOCK,
but not for EXCLUSIVE. To make this very clear have a look at
this table, where o means compatible or can coexist and
x means incompatible or can not coexist:
| NO LOCK | SHARED | EXCLUSIVE | |
| NO LOCK | o | o | o |
| SHARED | o | o | x |
| EXCLUSIVE | o | x | x |
Additionally, there are preferences for specific locks you can pass to
acquire(Object, int, boolean, int, boolean, long).
This means whenever more thanone party
waits for a lock you can specify which one is to be preferred. This gives you
every freedom you might need to specifcy e.g.
| Modifier and Type | Class and Description |
|---|---|
protected static class |
GenericLock.LockOwner |
| Modifier and Type | Field and Description |
|---|---|
protected LoggerFacade |
logger |
protected Map |
owners |
protected Object |
resourceId |
protected int |
waiters |
protected List |
waitingOwners |
COMPATIBILITY_NONE, COMPATIBILITY_REENTRANT, COMPATIBILITY_REENTRANT_AND_SUPPORT, COMPATIBILITY_SUPPORT| Constructor and Description |
|---|
GenericLock(Object resourceId,
int maxLockLevel,
LoggerFacade logger)
Creates a new lock.
|
| Modifier and Type | Method and Description |
|---|---|
boolean |
acquire(Object ownerId,
int targetLockLevel,
boolean wait,
boolean reentrant,
long timeoutMSecs)
Tries to acquire a certain lock level on this lock.
|
boolean |
acquire(Object ownerId,
int targetLockLevel,
boolean wait,
int compatibility,
boolean preferred,
long timeoutMSecs)
Tries to acquire a certain lock level on this lock.
|
boolean |
acquire(Object ownerId,
int targetLockLevel,
boolean wait,
int compatibility,
long timeoutMSecs) |
boolean |
acquire(Object ownerId,
int targetLockLevel,
boolean preferred,
long timeoutMSecs)
Tries to blockingly acquire a lock which can be preferred.
|
boolean |
equals(Object o) |
protected Set |
getConflictingOwners(GenericLock.LockOwner myOwner,
Collection ownersToTest) |
protected Set |
getConflictingOwners(Object ownerId,
int targetLockLevel,
int compatibility) |
protected Collection |
getConflictingWaiters(Object ownerId) |
int |
getLevelMaxLock()
Gets the highst lock level possible.
|
int |
getLevelMinLock()
Gets the lowest lock level possible.
|
int |
getLockLevel(Object ownerId)
Retuns the highest lock level the specified owner holds on this lock or
0 if it holds no locks at all. |
protected GenericLock.LockOwner |
getMaxLevelOwner() |
protected GenericLock.LockOwner |
getMaxLevelOwner(GenericLock.LockOwner reentrantOwner,
boolean preferred) |
protected GenericLock.LockOwner |
getMaxLevelOwner(GenericLock.LockOwner reentrantOwner,
int supportLockLevel,
boolean preferred) |
protected GenericLock.LockOwner |
getMaxLevelOwner(int supportLockLevel,
boolean preferred) |
Object |
getOwner() |
Object |
getResourceId()
Gets the resource assotiated to this lock.
|
boolean |
has(Object ownerId,
int lockLevel)
Tests if a certain lock level is owned by an owner.
|
int |
hashCode() |
protected boolean |
isCompatible(int targetLockLevel,
int currentLockLevel) |
protected void |
registerWaiter(GenericLock.LockOwner waitingOwner) |
boolean |
release(Object ownerId)
Releases any lock levels the specified owner may hold on this lock.
|
protected void |
setLockLevel(Object ownerId,
GenericLock.LockOwner lock,
int targetLockLevel,
int compatibility,
boolean intention) |
boolean |
test(Object ownerId,
int targetLockLevel,
int compatibility)
Tests if a certain lock level could be acquired.
|
String |
toString() |
protected boolean |
tryLock(Object ownerId,
int targetLockLevel,
int compatibility,
boolean preferred) |
protected boolean |
tryLock(Object ownerId,
int targetLockLevel,
int compatibility,
boolean preferred,
boolean tryOnly) |
protected void |
unregisterWaiter(GenericLock.LockOwner waitingOwner) |
protected Object resourceId
protected List waitingOwners
protected LoggerFacade logger
protected int waiters
public GenericLock(Object resourceId, int maxLockLevel, LoggerFacade logger)
resourceId - identifier for the resource associated to this lockmaxLockLevel - highest allowed lock level as described in class intrologger - generic logger used for all kind of debug loggingpublic boolean test(Object ownerId, int targetLockLevel, int compatibility)
MultiLevelLock2test in interface MultiLevelLock2ownerId - a unique id identifying the entity that wants to test a
certain lock level on this locktargetLockLevel - the lock level to acquirecompatibility - 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 supporttrue if the lock could be acquired at the time
this method was calledMultiLevelLock2.test(Object, int, int)public boolean has(Object ownerId, int lockLevel)
MultiLevelLock2has in interface MultiLevelLock2ownerId - a unique id identifying the entity that wants to check a
certain lock level on this locklockLevel - the lock level to testtrue if the lock could be acquired at the time
this method was calledMultiLevelLock2.has(Object, int)public boolean acquire(Object ownerId, int targetLockLevel, boolean wait, boolean reentrant, long timeoutMSecs) throws InterruptedException
MultiLevelLockacquire in interface MultiLevelLockownerId - a unique id identifying the entity that wants to acquire a certain lock level on this locktargetLockLevel - the lock level to acquirewait - true if this method shall block when the desired lock level can not be acquiredreentrant - true if lock levels of the same entity acquired earlier
should not restrict compatibility with the lock level desired nowtimeoutMSecs - if blocking is enabled by the wait parameter this specifies the maximum wait time in millisecondstrue if the lock actually was acquiredInterruptedException - when the thread waiting on this method is interruptedMultiLevelLock.acquire(java.lang.Object,
int, boolean, boolean, long)public boolean acquire(Object ownerId, int targetLockLevel, boolean wait, int compatibility, long timeoutMSecs) throws InterruptedException
public boolean acquire(Object ownerId, int targetLockLevel, boolean preferred, long timeoutMSecs) throws InterruptedException
InterruptedExceptionacquire(Object, int, boolean, int, boolean, long)public boolean acquire(Object ownerId, int targetLockLevel, boolean wait, int compatibility, boolean preferred, long timeoutMSecs) throws InterruptedException
MultiLevelLock2MultiLevelLock.acquire(java.lang.Object, int, boolean, boolean, long)
except that it allows for different compatibility settings. There is an
additional compatibility mode MultiLevelLock2.COMPATIBILITY_SUPPORTthat allows
equal lock levels not to interfere with each other. This is like an
additional shared compatibility and useful when you only want to make
sure not to interfer with lowe levels, but are fine with the same.acquire in interface MultiLevelLock2ownerId - a unique id identifying the entity that wants to acquire a certain lock level on this locktargetLockLevel - the lock level to acquirewait - true if this method shall block when the desired lock level can not be acquiredcompatibility - 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 supportpreferred - in case this lock request is incompatible with existing ones
and we wait, it shall be granted before other waiting requests
that are not preferredtimeoutMSecs - if blocking is enabled by the wait parameter this specifies the maximum wait time in millisecondstrue if the lock actually was acquiredInterruptedException - when the thread waiting on this method is interruptedMultiLevelLock2.acquire(Object,
int, boolean, int, boolean, long)protected void registerWaiter(GenericLock.LockOwner waitingOwner)
protected void unregisterWaiter(GenericLock.LockOwner waitingOwner)
public boolean release(Object ownerId)
MultiLevelLockrelease in interface MultiLevelLockownerId - a unique id identifying the entity that wants to release all lock levelstrue if the lock actually was released, false in case
there was no lock held by the ownerMultiLevelLock.release(Object)public int getLockLevel(Object ownerId)
MultiLevelLock0 if it holds no locks at all.getLockLevel in interface MultiLevelLockownerId - a unique id identifying the entity that wants to know its highest lock levelMultiLevelLock.getLockLevel(Object)public Object getResourceId()
public int getLevelMinLock()
public int getLevelMaxLock()
protected GenericLock.LockOwner getMaxLevelOwner()
protected GenericLock.LockOwner getMaxLevelOwner(GenericLock.LockOwner reentrantOwner, boolean preferred)
protected GenericLock.LockOwner getMaxLevelOwner(int supportLockLevel, boolean preferred)
protected GenericLock.LockOwner getMaxLevelOwner(GenericLock.LockOwner reentrantOwner, int supportLockLevel, boolean preferred)
protected void setLockLevel(Object ownerId, GenericLock.LockOwner lock, int targetLockLevel, int compatibility, boolean intention)
protected boolean tryLock(Object ownerId, int targetLockLevel, int compatibility, boolean preferred)
protected boolean tryLock(Object ownerId, int targetLockLevel, int compatibility, boolean preferred, boolean tryOnly)
protected boolean isCompatible(int targetLockLevel, int currentLockLevel)
protected Set getConflictingOwners(Object ownerId, int targetLockLevel, int compatibility)
protected Collection getConflictingWaiters(Object ownerId)
protected Set getConflictingOwners(GenericLock.LockOwner myOwner, Collection ownersToTest)
Copyright © 2004-2013 The Apache Software Foundation. All Rights Reserved.