Lock that is special due to how it handles deadlocks detection.
Is an inherent part of SingletonScope, moved into a upper level class due to its size
and complexity.
SingletonScope, com.google.inject.internal.CycleDetectingLock.CycleDetectingLockFactory
| Modifier and Type | Class and Description |
|---|---|
| public static class |
| Modifier and Type | Method and Description |
|---|---|
| public ListMultimap | lockOrDetectPotentialLocksCycle()
Takes a lock in a blocking fashion in case no potential deadlocks are detected. |
| public void |
| lockOrDetectPotentialLocksCycle | back to summary |
|---|---|
| public ListMultimap Takes a lock in a blocking fashion in case no potential deadlocks are detected. If the lock was successfully owned, returns an empty map indicating no detected potential deadlocks. Otherwise, a map indicating threads involved in a potential deadlock are returned. Map is ordered by dependency cycle and lists locks for each thread that are part of the loop in order, the last lock in the list is the one that the thread is currently waiting for. Returned map is created atomically. In case no cycle is detected performance is O(threads creating singletons), in case cycle is detected performance is O(singleton locks). | |
| unlock | back to summary |
|---|---|
| public void unlock() Unlocks previously locked lock. | |
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.
| Modifier and Type | Class and Description |
|---|---|
| pack-priv static class | CycleDetectingLock.
The implementation for |
| Modifier and Type | Field and Description |
|---|---|
| private static final Multimap | locksOwnedByThread
Lists locks that thread owns. |
| private static Map | lockThreadIsWaitingOn
Specifies lock that thread is currently waiting on to own it. |
| Access | Constructor and Description |
|---|---|
| public |
| Modifier and Type | Method and Description |
|---|---|
| pack-priv CycleDetectingLock | create(ID
lock id that would be used to report lock cycles if detected userLockId)Creates new lock within this factory context. |
| locksOwnedByThread | back to summary |
|---|---|
| private static final Multimap<Thread, CycleDetectingLock. Lists locks that thread owns. Used only to populate locks in a potential cycle when it is detected.
Element is added inside 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 | |
| lockThreadIsWaitingOn | back to summary |
|---|---|
| private static Map<Thread, CycleDetectingLock. Specifies lock that thread is currently waiting on to own it. Used only for purposes of locks cycle detection.
Element is added inside Same lock can be added for several threads in case all of them are trying to take it. Guarded by | |
| CycleDetectingLockFactory | back to summary |
|---|---|
| public CycleDetectingLockFactory() | |
| create | back to summary |
|---|---|
| pack-priv CycleDetectingLock Creates new lock within this factory context. We can guarantee that locks created by the same factory would not deadlock.
| |
CycleDetectingLock.
| Modifier and Type | Field and Description |
|---|---|
| private final CycleDetectingLock. | lockFactory
Factory that was used to create this lock. |
| private final Lock | lockImplementation
Underlying lock used for actual waiting when no potential deadlocks are detected. |
| private Thread | lockOwnerThread
Thread that owns this lock. |
| private int | lockReentranceCount
Number of times that thread owned this lock. |
| private final ID | userLockId
User id for this lock. |
| Access | Constructor and Description |
|---|---|
| pack-priv | ReentrantCycleDetectingLock(CycleDetectingLock.
|
| Modifier and Type | Method and Description |
|---|---|
| private CycleDetectingLock. | addAllLockIdsAfter(Thread thread, CycleDetectingLock.
Adds all locks held by the given thread that are after the given lock and then returns the lock the thread is currently waiting on, if any |
| pack-priv void | |
| private ListMultimap | |
| public ListMultimap | lockOrDetectPotentialLocksCycle()
Implements com. |
| public String | |
| public void | unlock()
Implements com. |
| lockFactory | back to summary |
|---|---|
| private final CycleDetectingLock. Factory that was used to create this lock. | |
| lockImplementation | back to summary |
|---|---|
| private final Lock lockImplementation Underlying lock used for actual waiting when no potential deadlocks are detected. | |
| lockOwnerThread | back to summary |
|---|---|
| private Thread lockOwnerThread Thread that owns this lock. Nullable. Guarded by | |
| lockReentranceCount | back to summary |
|---|---|
| private int lockReentranceCount Number of times that thread owned this lock. Guarded by | |
| userLockId | back to summary |
|---|---|
| private final ID userLockId User id for this lock. | |
| ReentrantCycleDetectingLock | back to summary |
|---|---|
| pack-priv ReentrantCycleDetectingLock(CycleDetectingLock. | |
| addAllLockIdsAfter | back to summary |
|---|---|
| private CycleDetectingLock. Adds all locks held by the given thread that are after the given lock and then returns the lock the thread is currently waiting on, if any | |
| checkState | back to summary |
|---|---|
| pack-priv void checkState() throws IllegalStateException Check consistency of an internal state. | |
| detectPotentialLocksCycle | back to summary |
|---|---|
| private ListMultimap Algorithm to detect a potential lock cycle. For lock's thread owner check which lock is it trying to take. Repeat recursively. When current thread is found a potential cycle is detected. | |
| lockOrDetectPotentialLocksCycle | back to summary |
|---|---|
| public ListMultimap Implements com. Doc from com. Takes a lock in a blocking fashion in case no potential deadlocks are detected. If the lock was successfully owned, returns an empty map indicating no detected potential deadlocks. Otherwise, a map indicating threads involved in a potential deadlock are returned. Map is ordered by dependency cycle and lists locks for each thread that are part of the loop in order, the last lock in the list is the one that the thread is currently waiting for. Returned map is created atomically. In case no cycle is detected performance is O(threads creating singletons), in case cycle is detected performance is O(singleton locks).
| |
| toString | back to summary |
|---|---|
| public String toString() Overrides java. Doc from java. Returns a string representation of the object. | |
| unlock | back to summary |
|---|---|
| public void unlock() Implements com. Doc from com. Unlocks previously locked lock.
| |