Class CycleDetectingLock.CycleDetectingLockFactory<ID>
- java.lang.Object
-
- com.google.inject.internal.CycleDetectingLock.CycleDetectingLockFactory<ID>
-
- Enclosing interface:
- CycleDetectingLock<ID>
public static class CycleDetectingLock.CycleDetectingLockFactory<ID> extends java.lang.Object
Wraps locks so they would never cause a deadlock. On eachCycleDetectingLock.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 Classes Modifier and Type Class Description (package private) static class
CycleDetectingLock.CycleDetectingLockFactory.ReentrantCycleDetectingLock<ID>
The implementation forCycleDetectingLock
.
-
Field Summary
Fields Modifier and Type Field Description private static com.google.common.collect.Multimap<java.lang.Thread,CycleDetectingLock.CycleDetectingLockFactory.ReentrantCycleDetectingLock<?>>
locksOwnedByThread
Lists locks that thread owns.private static java.util.Map<java.lang.Thread,CycleDetectingLock.CycleDetectingLockFactory.ReentrantCycleDetectingLock<?>>
lockThreadIsWaitingOn
Specifies lock that thread is currently waiting on to own it.
-
Constructor Summary
Constructors Constructor Description CycleDetectingLockFactory()
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description (package private) CycleDetectingLock<ID>
create(ID userLockId)
Creates new lock within this factory context.
-
-
-
Field Detail
-
lockThreadIsWaitingOn
private static java.util.Map<java.lang.Thread,CycleDetectingLock.CycleDetectingLockFactory.ReentrantCycleDetectingLock<?>> lockThreadIsWaitingOn
Specifies 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<java.lang.Thread,CycleDetectingLock.CycleDetectingLockFactory.ReentrantCycleDetectingLock<?>> locksOwnedByThread
Lists 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
.
-
-
Method Detail
-
create
CycleDetectingLock<ID> create(ID userLockId)
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
-
-