To achieve its requirements,
the DefaultComponentKeeper
synchronizes on 3 different maps
(componentMap
, creationLocks
and
nascentComponents
) and the values contained within
creationLocks
referred to as
creation lock objects. When the DefaultComponentKeeper
uses nested synchronization, it synchronizes on a creation lock
object first, then either componentMap
or
nascentComponents
. Synchronization is never nested more than
2 deep. Neither creationLocks
nor creation lock objects
are synchronized within another synchronization block.
A lock on componentMap
is required any time a request is made
to get, add, or remove a component from componentMap
. The lock
is also required when destroyAllComponents
is called for the
duration of the call. This ensures that once destroyAllComponents
starts, no other requests are serviced until the the call ends.
A lock on creationLocks
is required any time a request is made
to get a component lock. Adds are implicit within gets and removes are
not allowed. A creation lock is only required when a component that
does not yet exist is requestes.
For each Component created, there is one creation lock object. This object
is created upon the first request for the Component. It is then used
synchronized during component creation
to ensure that only one thread creates a component.
nascentComponents
is a temporary place to store components
while they are having their dependancies resolved. This is how circular
dependancies are resolved. Synchronization on nascentComponents
is required when components are retrieved, added, or removed. These
operations are only done during component creation.
|
- All gets from
componentMap happen one at a time. This means
that the fetchComponent method can only serve one component at
a time where the components requested already exist. Note that component
creations do not happen within this lock so creations do not affect gets.
- All
fetchNewComponent requests must go through the same critical
section of code to get a creation lock object.
While one thread is getting a creation lock object,
no other thread can get one. This is also
true when components are retrieved, added, or removed from
nascentComponents . Both of these synchronizations are
for the span of a Map manipulation. This means that
fetchNewComponent calls interfere with each other, but do
not block each other (unless they synchronize on the same component
lock, i.e. are fetching the same component).
|