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)
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 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)
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 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
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 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
InterruptedException
acquire(Object, int, boolean, int, boolean, long)
public boolean acquire(Object ownerId, int targetLockLevel, boolean wait, int compatibility, boolean preferred, long timeoutMSecs) throws 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 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)
MultiLevelLock
release
in interface MultiLevelLock
ownerId
- 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)
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 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.