public class BasicIntegerIdPool
extends java.lang.Object
Pool of integer IDs. The pool is both thread safe and lock free. IDs are
acquired and released as primitive integer numbers, so the caller is
responsible for making sure that it does not use an ID after it has been
released and that it does not release an ID that has not been acquired or has
already been released. For a more self-contained variant see
IntegerIdPool
.
The pool generates integer IDs from a configurable range, ensuring that each ID is only handed out once. In order to accommodate for applications that need a large number of IDs over their life-cycle, the pool supports the reuse of IDs if they are released when they are not needed any longer.
Optionally, the pool can be configured to block released IDs from immediate reuse for a certain time. This is useful in environments where IDs leave the scope of the application and thus external entities might have dangling references to those IDs. In this case, configuring a time for which the ID is blocked from reuse after having been released can help in avoiding a situation in which an external entity uses an ID that has now been reused for a different purpose.
Internally, this implementation uses a SimpleConcurrentQueue
for
keeping a list of IDs that have been released and can be reused. If this list
is empty, a completely new ID is acquired by incrementing an atomic counter
that keeps track of the IDs that have never been used.
This implementation is more efficient than keeping a list of IDs in use and checking incrementally growing IDs against this list. While such an algorithm would have a worst-case performance of O(n) for acquire operations, this implementation has O(1) performance for both acquire and release operations. This advantage comes at the cost of a significant memory footprint if a large number of IDs is acquired, subsequently released, and no IDs are acquired subsequently. In this case, this pool uses memory proportional to the number of IDs that have been in use in parallel.
Constructor and Description |
---|
BasicIntegerIdPool(int minimumId,
int maximumId,
long blockFromReuseTime,
boolean earlyReuseOnExhaustion)
Creates a new pool for integer IDs.
|
Modifier and Type | Method and Description |
---|---|
int |
acquireId()
Acquires an ID that is currently not in use.
|
void |
releaseId(int id)
Releases an ID.
|
public BasicIntegerIdPool(int minimumId, int maximumId, long blockFromReuseTime, boolean earlyReuseOnExhaustion)
Creates a new pool for integer IDs. All IDs returned by the pools
acquireId()
method are guaranteed to be in the range from
minimumId
to maximumId
(both inclusive).
If minimumId
is greater than maximumId
, the
pool will start at minimumId
counting upwards until
Integer.MAX_VALUE
is reached. Then, the counter will wrap around
continuing with negative numbers until maximumId
is reached.
minimumId
and maximumId
must be chosen so that
there is at least one integer number that is not covered by the range.
This number is needed because it will be internally used as a marker when
the counter has been exhausted.
The blockFromReuseTime
parameter specifies the amount of
time in milliseconds that must pass between an ID being returned by
calling releaseId(int)
and acquireId()
returning the
same ID. This is useful for applications where an external entity might
keep an ID for some time and it is important to distinguish the now
invalid ID from newly acquired IDs.
If earlyReuseOnExhaustion
is true
,
acquireId()
will not fail immediately if no ID can be reused yet
and no new ID can be assigned because all possible IDs are already in
use. Instead of that, it will try to find an ID that has been released,
but for which the blockFromReuseTime
has not passed yet.
This can be used as a last resort, when it is more important to make sure
that IDs can be acquired than it is important to ensure that released IDs
are not reused for a certain time.
minimumId
- minimum number used as an ID (inclusive). If
minimumId
is greater than maximumId
,
IDs that are less than minimumId
are used if they
are also less than or equal to maximumId
.maximumId
- maximum number used as an ID (inclusive). If
maximumId
is less than minimumId
,
IDs that are greater than maximumId
are used if
they are also greater than or equal to minimumId
.blockFromReuseTime
- number of milliseconds to wait before reusing an ID after it
has been released. A value of 0
means that IDs
can be reused immediately.earlyReuseOnExhaustion
- if true
IDs which have been released less than
blockFromReuseTime
milliseconds ago are still
used if otherwise the pool would be exhausted.java.lang.IllegalArgumentException
- if minimumId
and maximumId
have not
been chosen so that there is at least one unusable ID or if
blockFromReuseTime is negative.public int acquireId()
releaseId(int)
method.releaseId(int)
when it is not needed any longer.java.lang.IllegalStateException
- if this pool is exhausted and no unused ID can be assigned at
the moment.public void releaseId(int id)
acquireId()
. If a non-zero block-from-reuse time has been set,
the released ID will not be returned by acquireId()
before this
time has passed.id
- ID that is not used any longer and should be put back into the
pool of available IDs.Copyright © 2014–2017 aquenos GmbH. All rights reserved.