|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectorg.apache.fulcrum.yaafi.framework.locking.GenericLock
public class GenericLock
A generic implementaion of a simple multi level lock.
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.
Nested Class Summary | |
---|---|
protected static class |
GenericLock.LockOwner
|
Field Summary | |
---|---|
protected LoggerFacade |
logger
|
protected java.util.Map |
owners
|
protected java.lang.Object |
resourceId
|
protected int |
waiters
|
protected java.util.List |
waitingOwners
|
Fields inherited from interface org.apache.fulcrum.yaafi.framework.locking.MultiLevelLock2 |
---|
COMPATIBILITY_NONE, COMPATIBILITY_REENTRANT, COMPATIBILITY_REENTRANT_AND_SUPPORT, COMPATIBILITY_SUPPORT |
Constructor Summary | |
---|---|
GenericLock(java.lang.Object resourceId,
int maxLockLevel,
LoggerFacade logger)
Creates a new lock. |
Method Summary | |
---|---|
boolean |
acquire(java.lang.Object ownerId,
int targetLockLevel,
boolean wait,
boolean reentrant,
long timeoutMSecs)
Tries to acquire a certain lock level on this lock. |
boolean |
acquire(java.lang.Object ownerId,
int targetLockLevel,
boolean wait,
int compatibility,
boolean preferred,
long timeoutMSecs)
Tries to acquire a certain lock level on this lock. |
boolean |
acquire(java.lang.Object ownerId,
int targetLockLevel,
boolean wait,
int compatibility,
long timeoutMSecs)
|
boolean |
acquire(java.lang.Object ownerId,
int targetLockLevel,
boolean preferred,
long timeoutMSecs)
Tries to blockingly acquire a lock which can be preferred. |
boolean |
equals(java.lang.Object o)
|
protected java.util.Set |
getConflictingOwners(GenericLock.LockOwner myOwner,
java.util.Collection ownersToTest)
|
protected java.util.Set |
getConflictingOwners(java.lang.Object ownerId,
int targetLockLevel,
int compatibility)
|
protected java.util.Collection |
getConflictingWaiters(java.lang.Object ownerId)
|
int |
getLevelMaxLock()
Gets the highst lock level possible. |
int |
getLevelMinLock()
Gets the lowest lock level possible. |
int |
getLockLevel(java.lang.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)
|
java.lang.Object |
getOwner()
|
java.lang.Object |
getResourceId()
Gets the resource assotiated to this lock. |
boolean |
has(java.lang.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(java.lang.Object ownerId)
Releases any lock levels the specified owner may hold on this lock. |
protected void |
setLockLevel(java.lang.Object ownerId,
GenericLock.LockOwner lock,
int targetLockLevel,
int compatibility,
boolean intention)
|
boolean |
test(java.lang.Object ownerId,
int targetLockLevel,
int compatibility)
Tests if a certain lock level could be acquired. |
java.lang.String |
toString()
|
protected boolean |
tryLock(java.lang.Object ownerId,
int targetLockLevel,
int compatibility,
boolean preferred)
|
protected boolean |
tryLock(java.lang.Object ownerId,
int targetLockLevel,
int compatibility,
boolean preferred,
boolean tryOnly)
|
protected void |
unregisterWaiter(GenericLock.LockOwner waitingOwner)
|
Methods inherited from class java.lang.Object |
---|
clone, finalize, getClass, notify, notifyAll, wait, wait, wait |
Field Detail |
---|
protected java.lang.Object resourceId
protected java.util.Map owners
protected java.util.List waitingOwners
protected LoggerFacade logger
protected int waiters
Constructor Detail |
---|
public GenericLock(java.lang.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 loggingMethod Detail |
---|
public boolean equals(java.lang.Object o)
equals
in class java.lang.Object
public int hashCode()
hashCode
in class java.lang.Object
public boolean test(java.lang.Object ownerId, int targetLockLevel, int compatibility)
MultiLevelLock2
test
in interface MultiLevelLock2
ownerId
- a unique id identifying the entity that wants to test a
certain lock level on this locktargetLockLevel
- the lock level to acquirecompatibility
- MultiLevelLock2.COMPATIBILITY_NONE
if no additional compatibility is
desired (same as reentrant set to false) ,
MultiLevelLock2.COMPATIBILITY_REENTRANT
if lock level by the same
owner shall not affect compatibility (same as reentrant set to
true), or MultiLevelLock2.COMPATIBILITY_SUPPORT
if lock levels that
are the same as the desired shall not affect compatibility, or
finally MultiLevelLock2.COMPATIBILITY_REENTRANT_AND_SUPPORT
which is
a combination of reentrant and support
true
if the lock could be acquired at the time
this method was calledMultiLevelLock2.test(Object, int, int)
public boolean has(java.lang.Object ownerId, int lockLevel)
MultiLevelLock2
has
in interface MultiLevelLock2
ownerId
- a unique id identifying the entity that wants to check a
certain lock level on this locklockLevel
- the lock level to test
true
if the lock could be acquired at the time
this method was calledMultiLevelLock2.has(Object, int)
public boolean acquire(java.lang.Object ownerId, int targetLockLevel, boolean wait, boolean reentrant, long timeoutMSecs) throws java.lang.InterruptedException
MultiLevelLock
acquire
in interface MultiLevelLock
ownerId
- 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 milliseconds
true
if the lock actually was acquired
java.lang.InterruptedException
- when the thread waiting on this method is interruptedMultiLevelLock.acquire(java.lang.Object,
int, boolean, boolean, long)
public boolean acquire(java.lang.Object ownerId, int targetLockLevel, boolean wait, int compatibility, long timeoutMSecs) throws java.lang.InterruptedException
java.lang.InterruptedException
acquire(Object, int, boolean, int, boolean, long)
public boolean acquire(java.lang.Object ownerId, int targetLockLevel, boolean preferred, long timeoutMSecs) throws java.lang.InterruptedException
java.lang.InterruptedException
acquire(Object, int, boolean, int, boolean, long)
public boolean acquire(java.lang.Object ownerId, int targetLockLevel, boolean wait, int compatibility, boolean preferred, long timeoutMSecs) throws java.lang.InterruptedException
MultiLevelLock2
MultiLevelLock.acquire(java.lang.Object, int, boolean, boolean, long)
except that it allows for different compatibility settings. There is an
additional compatibility mode MultiLevelLock2.COMPATIBILITY_SUPPORT
that 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 MultiLevelLock2
ownerId
- 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_NONE
if no additional compatibility is
desired (same as reentrant set to false) ,
MultiLevelLock2.COMPATIBILITY_REENTRANT
if lock level by the same
owner shall not affect compatibility (same as reentrant set to
true), or MultiLevelLock2.COMPATIBILITY_SUPPORT
if lock levels that
are the same as the desired shall not affect compatibility, or
finally MultiLevelLock2.COMPATIBILITY_REENTRANT_AND_SUPPORT
which 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 milliseconds
true
if the lock actually was acquired
java.lang.InterruptedException
- 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(java.lang.Object ownerId)
MultiLevelLock
release
in interface MultiLevelLock
ownerId
- a unique id identifying the entity that wants to release all lock levels
true
if the lock actually was released, false
in case
there was no lock held by the ownerMultiLevelLock.release(Object)
public int getLockLevel(java.lang.Object ownerId)
MultiLevelLock
0
if it holds no locks at all.
getLockLevel
in interface MultiLevelLock
ownerId
- a unique id identifying the entity that wants to know its highest lock level
MultiLevelLock.getLockLevel(Object)
public java.lang.Object getResourceId()
public int getLevelMinLock()
public int getLevelMaxLock()
public java.lang.Object getOwner()
public java.lang.String toString()
toString
in class java.lang.Object
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(java.lang.Object ownerId, GenericLock.LockOwner lock, int targetLockLevel, int compatibility, boolean intention)
protected boolean tryLock(java.lang.Object ownerId, int targetLockLevel, int compatibility, boolean preferred)
protected boolean tryLock(java.lang.Object ownerId, int targetLockLevel, int compatibility, boolean preferred, boolean tryOnly)
protected boolean isCompatible(int targetLockLevel, int currentLockLevel)
protected java.util.Set getConflictingOwners(java.lang.Object ownerId, int targetLockLevel, int compatibility)
protected java.util.Collection getConflictingWaiters(java.lang.Object ownerId)
protected java.util.Set getConflictingOwners(GenericLock.LockOwner myOwner, java.util.Collection ownersToTest)
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |