Utility class that can be used to implement
queues with limited capacity (in terms of memory).
It maintains internal counter and provides
two operations: increase and decrease.
Increase blocks until internal counter is lower than
given threshold and then increases internal counter.
Decrease decreases internal counter and wakes up
waiting threads if counter is lower than threshold.
This implementation allows you to set the value of internal
counter to be greater than threshold. It happens
when internal counter is lower than threshold and
increase method is called with parameter 'delta' big enough
so that sum of delta and internal counter is greater than
threshold. This is not a bug, this is a feature.
It solves some problems:
- thread calling increase with big parameter will not be
starved by other threads calling increase with small
- thread calling increase with argument greater than
threshold won't deadlock. This is useful when throttling
queues - you can submit object that is bigger than limit.
This implementation introduces small costs in terms of
synchronization (no synchronization in most cases at all), but is
vulnerable to races. For details see documentation of
Blocks until internal counter is lower than threshold
and then increases value of internal counter.
THIS METHOD IS VULNERABLE TO RACES.
It may happen that increment operation will
succeed immediately, even if it should block. This happens when
at least two threads call increase at the some moment. The decision
whether to block is made at the beginning, without synchronization.
If value of currentSize is lower than threshold at that time, call
will succeed immediately. It is possible, that 2 threads will make
decision not to block, even if one of them should block.