Class ConcurrentLockSet
- java.lang.Object
-
- org.apache.derby.impl.services.locks.ConcurrentLockSet
-
- All Implemented Interfaces:
LockTable
final class ConcurrentLockSet extends java.lang.Object implements LockTable
A ConcurrentLockSet is a complete lock table which mapsLockable
s toLockControl
objects.A LockControl contains information about the locks held on a Lockable.
MT - Mutable : All public methods of this class, except addWaiters, are thread safe. addWaiters can only be called from the thread which performs deadlock detection. Only one thread can perform deadlock detection at a time.
The class creates ActiveLock and LockControl objects. LockControl objects are never passed out of this class, All the methods of LockControl are called while holding a ReentrantLock associated with the Lockable controlled by the LockControl, thus providing the single threading that LockControl required. Methods of Lockables are only called by this class or LockControl, and always while holding the corresponding ReentrantLock, thus providing the single threading that Lockable requires.- See Also:
LockControl
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description private static class
ConcurrentLockSet.Entry
Class representing an entry in the lock table.
-
Field Summary
Fields Modifier and Type Field Description private java.util.concurrent.atomic.AtomicInteger
blockCount
private int
deadlockTimeout
Timeout for deadlocks, in ms.private boolean
deadlockTrace
private AbstractPool
factory
private java.util.concurrent.ConcurrentHashMap<Lockable,ConcurrentLockSet.Entry>
locks
Hash table which mapsLockable
objects toLock
s.private java.util.ArrayList<ConcurrentLockSet.Entry>
seenByDeadlockDetection
List containing all entries seen by the last call toaddWaiters()
.private int
waitTimeout
-
Constructor Summary
Constructors Constructor Description ConcurrentLockSet(AbstractPool factory)
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description void
addWaiters(java.util.Map<java.lang.Object,java.lang.Object> waiters)
Add all waiters in this lock table to aMap
object.boolean
anyoneBlocked()
Check whether anyone is blocked.private java.lang.Object[]
checkDeadlock(ConcurrentLockSet.Entry entry, ActiveLock waitingLock, byte wakeupReason)
Check whether there is a deadlock.private ConcurrentLockSet.Entry
getEntry(Lockable ref)
Get an entry from the lock table.int
getWaitTimeout()
Get the wait timeout in milliseconds.Lock
lockObject(CompatibilitySpace compatibilitySpace, Lockable ref, java.lang.Object qualifier, int timeout)
Lock an object within a specific compatibility space.void
oneLessWaiter()
Decrease blockCount by one.void
oneMoreWaiter()
Increase blockCount by one.void
setDeadlockTimeout(int timeout)
Set the deadlock timeout.void
setDeadlockTrace(boolean val)
Enable or disable tracing of deadlocks.void
setWaitTimeout(int timeout)
Set the wait timeout.java.util.Map<Lockable,Control>
shallowClone()
make a shallow clone of myself and my lock controlsprivate java.lang.String
toDebugString()
void
unlock(Latch item, int unlockCount)
Unlock an object, previously locked by lockObject().private void
unlock(ConcurrentLockSet.Entry entry, Latch item, int unlockCount)
Unlock an object, previously locked by lockObject().Lock
unlockReference(CompatibilitySpace space, Lockable ref, java.lang.Object qualifier, java.util.Map group)
Unlock an object once if it is present in the specified group.boolean
zeroDurationLockObject(CompatibilitySpace space, Lockable ref, java.lang.Object qualifier, int timeout)
Lock an object and release the lock immediately.
-
-
-
Field Detail
-
factory
private final AbstractPool factory
-
locks
private final java.util.concurrent.ConcurrentHashMap<Lockable,ConcurrentLockSet.Entry> locks
Hash table which mapsLockable
objects toLock
s.
-
seenByDeadlockDetection
private java.util.ArrayList<ConcurrentLockSet.Entry> seenByDeadlockDetection
List containing all entries seen by the last call toaddWaiters()
. Makes it possible for the deadlock detection thread to lock all the entries it has visited until it has finished. This prevents false deadlocks from being reported (because all observed waiters must still be waiting when the deadlock detection has completed).
-
deadlockTimeout
private int deadlockTimeout
Timeout for deadlocks, in ms.
MT - immutable
-
waitTimeout
private int waitTimeout
-
deadlockTrace
private boolean deadlockTrace
-
blockCount
private final java.util.concurrent.atomic.AtomicInteger blockCount
-
-
Constructor Detail
-
ConcurrentLockSet
ConcurrentLockSet(AbstractPool factory)
-
-
Method Detail
-
getEntry
private ConcurrentLockSet.Entry getEntry(Lockable ref)
Get an entry from the lock table. If no entry exists for theLockable
, insert an entry. The returned entry will be locked and is guaranteed to still be present in the table.- Parameters:
ref
- theLockable
whose entry to return- Returns:
- the entry for the
Lockable
, locked for exclusive access
-
checkDeadlock
private java.lang.Object[] checkDeadlock(ConcurrentLockSet.Entry entry, ActiveLock waitingLock, byte wakeupReason)
Check whether there is a deadlock. Make sure that only one thread enters deadlock detection at a time.- Parameters:
entry
- the entry in the lock table for the lock request that triggered deadlock detectionwaitingLock
- the waiting lockwakeupReason
- the reason for waking up the waiter- Returns:
- an object describing the deadlock
-
lockObject
public Lock lockObject(CompatibilitySpace compatibilitySpace, Lockable ref, java.lang.Object qualifier, int timeout) throws StandardException
Lock an object within a specific compatibility space.- Specified by:
lockObject
in interfaceLockTable
- Parameters:
compatibilitySpace
- Compatibility space.ref
- Lockable reference.qualifier
- Qualifier.timeout
- Timeout in milli-seconds- Returns:
- Object that represents the lock.
- Throws:
StandardException
- Standard Derby policy.
-
unlock
public void unlock(Latch item, int unlockCount)
Unlock an object, previously locked by lockObject(). If unlockCOunt is not zero then the lock will be unlocked that many times, otherwise the unlock count is taken from item.
-
unlock
private void unlock(ConcurrentLockSet.Entry entry, Latch item, int unlockCount)
Unlock an object, previously locked by lockObject().- Parameters:
entry
- the entry in which the lock is contained (the current thread must have locked the entry)item
- the item to unlockunlockCount
- the number of times to unlock the item (if zero, take the unlock count from item)
-
unlockReference
public Lock unlockReference(CompatibilitySpace space, Lockable ref, java.lang.Object qualifier, java.util.Map group)
Unlock an object once if it is present in the specified group. Also remove the object from the group.- Specified by:
unlockReference
in interfaceLockTable
- Parameters:
space
- the compatibility spaceref
- a reference to the locked objectqualifier
- qualifier of the lockgroup
- a map representing the locks in a group- Returns:
- the corresponding lock in the group map, or
null
if the object was not unlocked
-
zeroDurationLockObject
public boolean zeroDurationLockObject(CompatibilitySpace space, Lockable ref, java.lang.Object qualifier, int timeout) throws StandardException
Lock an object and release the lock immediately. Equivalent toLock lock = lockTable.lockObject(space, ref, qualifier, timeout); lockTable.unlock(lock, 1);
except that the implementation might be more efficient.- Specified by:
zeroDurationLockObject
in interfaceLockTable
- Parameters:
space
- the compatibility spaceref
- a reference to the locked objectqualifier
- qualifier of the locktimeout
- maximum time to wait in milliseconds (C_LockFactory.NO_WAIT
means don't wait)- Returns:
true
if the object was locked, orfalse
if the object couldn't be locked immediately and timeout wasNO_WAIT
orLockOwner
had thenoWait
flag set- Throws:
StandardException
- if the lock could not be obtained
-
setDeadlockTimeout
public void setDeadlockTimeout(int timeout)
Set the deadlock timeout.- Specified by:
setDeadlockTimeout
in interfaceLockTable
- Parameters:
timeout
- deadlock timeout in milliseconds
-
setWaitTimeout
public void setWaitTimeout(int timeout)
Set the wait timeout.- Specified by:
setWaitTimeout
in interfaceLockTable
- Parameters:
timeout
- wait timeout in milliseconds
-
getWaitTimeout
public int getWaitTimeout()
Get the wait timeout in milliseconds.- Specified by:
getWaitTimeout
in interfaceLockTable
-
setDeadlockTrace
public void setDeadlockTrace(boolean val)
Description copied from interface:LockTable
Enable or disable tracing of deadlocks.- Specified by:
setDeadlockTrace
in interfaceLockTable
- Parameters:
val
-true
enables tracing,false
disables tracing
-
toDebugString
private java.lang.String toDebugString()
-
addWaiters
public void addWaiters(java.util.Map<java.lang.Object,java.lang.Object> waiters)
Add all waiters in this lock table to aMap
object. This method can only be called by the thread that is currently performing deadlock detection. All entries that are visited in the lock table will be locked when this method returns. The entries that have been seen and locked will be unlocked after the deadlock detection has finished.- Specified by:
addWaiters
in interfaceLockTable
- Parameters:
waiters
- the map to add the waiters to- See Also:
LockControl.addWaiters(java.util.Map<java.lang.Object, java.lang.Object>)
-
shallowClone
public java.util.Map<Lockable,Control> shallowClone()
make a shallow clone of myself and my lock controls- Specified by:
shallowClone
in interfaceLockTable
- Returns:
- a shallow clone of the lock table
-
oneMoreWaiter
public void oneMoreWaiter()
Increase blockCount by one.- Specified by:
oneMoreWaiter
in interfaceLockTable
-
oneLessWaiter
public void oneLessWaiter()
Decrease blockCount by one.- Specified by:
oneLessWaiter
in interfaceLockTable
-
anyoneBlocked
public boolean anyoneBlocked()
Check whether anyone is blocked.- Specified by:
anyoneBlocked
in interfaceLockTable
- Returns:
true
if someone is blocked,false
otherwise
-
-