Class CycleDetectingLock.CycleDetectingLockFactory<ID>
- Enclosing interface:
- CycleDetectingLock<ID>
CycleDetectingLock.lockOrDetectPotentialLocksCycle()
we check for dependency cycles within locks
created by the same factory. Either we detect a cycle and return it or take it atomically.
Important to note that we do not prevent deadlocks in the client code. As an example: Thread A takes lock L and creates singleton class CA depending on the singleton class CB. Meanwhile thread B is creating class CB and is waiting on the lock L. Issue happens due to client code creating interdependent classes and using locks, where no guarantees on the creation order from Guice are provided.
Instances of these locks are not intended to be exposed outside of SingletonScope
.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescription(package private) static class
The implementation forCycleDetectingLock
. -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate static final com.google.common.collect.Multimap<Thread,
CycleDetectingLock.CycleDetectingLockFactory.ReentrantCycleDetectingLock<?>> Lists locks that thread owns.private static Map<Thread,
CycleDetectingLock.CycleDetectingLockFactory.ReentrantCycleDetectingLock<?>> Specifies lock that thread is currently waiting on to own it. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescription(package private) CycleDetectingLock<ID>
Creates new lock within this factory context.
-
Field Details
-
lockThreadIsWaitingOn
private static Map<Thread,CycleDetectingLock.CycleDetectingLockFactory.ReentrantCycleDetectingLock<?>> lockThreadIsWaitingOnSpecifies lock that thread is currently waiting on to own it. Used only for purposes of locks cycle detection.- Key: thread
- Value: lock that is being waited on
Element is added inside
CycleDetectingLock.lockOrDetectPotentialLocksCycle()
beforeLock.lock()
is called. Element is removed insideCycleDetectingLock.lockOrDetectPotentialLocksCycle()
afterLock.lock()
and synchronously with adding it tolocksOwnedByThread
.Same lock can be added for several threads in case all of them are trying to take it.
Guarded by
CycleDetectingLockFactory.class
. -
locksOwnedByThread
private static final com.google.common.collect.Multimap<Thread,CycleDetectingLock.CycleDetectingLockFactory.ReentrantCycleDetectingLock<?>> locksOwnedByThreadLists locks that thread owns. Used only to populate locks in a potential cycle when it is detected.- Key: thread
- Value: stack of locks that were owned.
Element is added inside
CycleDetectingLock.lockOrDetectPotentialLocksCycle()
afterLock.lock()
is called. Element is removed insideCycleDetectingLock.unlock()
synchronously withLock.unlock()
call.Same lock can only be present several times for the same thread as locks are reentrant. Lock can not be owned by several different threads as the same time.
Guarded by
CycleDetectingLockFactory.class
.
-
-
Constructor Details
-
CycleDetectingLockFactory
public CycleDetectingLockFactory()
-
-
Method Details
-
create
Creates new lock within this factory context. We can guarantee that locks created by the same factory would not deadlock.- Parameters:
userLockId
- lock id that would be used to report lock cycles if detected
-