public abstract class WaitStrategy extends Object
LongSupplier
values with various spinning strategies.Modifier and Type | Field and Description |
---|---|
static Runnable |
NOOP_SPIN_OBSERVER
A no-op
Runnable that can be used as a placeholder spin observer with
waitFor(long, LongSupplier, Runnable) |
Constructor and Description |
---|
WaitStrategy() |
Modifier and Type | Method and Description |
---|---|
static void |
alert()
Throw an Alert signal exception (singleton) that can be checked against
isAlert(Throwable) |
static WaitStrategy |
blocking()
Blocking strategy that uses a lock and condition variable for consumer waiting on a barrier.
|
static WaitStrategy |
busySpin()
Busy Spin strategy that uses a busy spin loop for consumers waiting on a barrier.
|
static boolean |
isAlert(Throwable t)
Test if exception is alert
|
static WaitStrategy |
liteBlocking()
Variation of the
blocking() that attempts to elide conditional wake-ups when the lock is uncontended. |
static WaitStrategy |
parking()
Parking strategy that initially spins, then uses a Thread.yield(), and eventually sleep
(
LockSupport.parkNanos(1) ) for the minimum number of nanos the OS and JVM will allow while the
consumers are waiting on a barrier. |
static WaitStrategy |
parking(int retries)
Parking strategy that initially spins, then uses a Thread.yield(), and eventually
sleep (
LockSupport.parkNanos(1) ) for the minimum number of nanos the
OS and JVM will allow while the consumers are waiting on a barrier. |
static WaitStrategy |
phasedOff(long spinTimeout,
long yieldTimeout,
TimeUnit units,
WaitStrategy delegate)
Phased wait strategy for waiting consumers on a barrier.
|
static WaitStrategy |
phasedOffLiteLock(long spinTimeout,
long yieldTimeout,
TimeUnit units)
Block with wait/notifyAll semantics
|
static WaitStrategy |
phasedOffLock(long spinTimeout,
long yieldTimeout,
TimeUnit units)
Block with wait/notifyAll semantics
|
static WaitStrategy |
phasedOffSleep(long spinTimeout,
long yieldTimeout,
TimeUnit units)
Block by parking in a loop
|
void |
signalAllWhenBlocking()
Implementations should signal the waiting consumers that the cursor has advanced.
|
static WaitStrategy |
sleeping()
Yielding strategy that uses a Thread.sleep(1) for consumers waiting on a
barrier
after an initially spinning.
|
abstract long |
waitFor(long sequence,
LongSupplier cursor,
Runnable spinObserver)
Wait for the given sequence to be available.
|
static WaitStrategy |
yielding()
Yielding strategy that uses a Thread.yield() for consumers waiting on a
barrier
after an initially spinning.
|
public static final Runnable NOOP_SPIN_OBSERVER
Runnable
that can be used as a placeholder spin observer with
waitFor(long, LongSupplier, Runnable)
public static WaitStrategy blocking()
public static WaitStrategy busySpin()
public static boolean isAlert(Throwable t)
t
- exception checkedpublic static WaitStrategy liteBlocking()
blocking()
that attempts to elide conditional wake-ups when the lock is uncontended.
Shows performance improvements on microbenchmarks. However this wait strategy should be considered experimental
as I have not full proved the correctness of the lock elision code.public static WaitStrategy parking()
LockSupport.parkNanos(1)
) for the minimum number of nanos the OS and JVM will allow while the
consumers are waiting on a barrier.
This strategy is a good compromise between performance and CPU resource. Latency spikes can occur after quiet periods.
public static WaitStrategy parking(int retries)
LockSupport.parkNanos(1)
) for the minimum number of nanos the
OS and JVM will allow while the consumers are waiting on a barrier.
This strategy is a good compromise between performance and CPU resource. Latency spikes can occur after quiet periods.
retries
- the spin cycle count before parkingpublic static WaitStrategy phasedOff(long spinTimeout, long yieldTimeout, TimeUnit units, WaitStrategy delegate)
Phased wait strategy for waiting consumers on a barrier.
This strategy can be used when throughput and low-latency are not as important as CPU resource. Spins, then yields, then waits using the configured fallback WaitStrategy.
spinTimeout
- the spin timeoutyieldTimeout
- the yield timeoutunits
- the time unitdelegate
- the target wait strategy to fallback onpublic static WaitStrategy phasedOffLiteLock(long spinTimeout, long yieldTimeout, TimeUnit units)
spinTimeout
- the spin timeoutyieldTimeout
- the yield timeoutunits
- the time unitpublic static WaitStrategy phasedOffLock(long spinTimeout, long yieldTimeout, TimeUnit units)
spinTimeout
- the spin timeoutyieldTimeout
- the yield timeoutunits
- the time unitpublic static WaitStrategy phasedOffSleep(long spinTimeout, long yieldTimeout, TimeUnit units)
spinTimeout
- the spin timeoutyieldTimeout
- the yield timeoutunits
- the time unitpublic static WaitStrategy sleeping()
public static WaitStrategy yielding()
public void signalAllWhenBlocking()
public abstract long waitFor(long sequence, LongSupplier cursor, Runnable spinObserver) throws InterruptedException
sequence
- to be waited on.cursor
- the main sequence from ringbuffer. Wait/notify strategies will
need this as is notified upon update.spinObserver
- Spin observerInterruptedException
- if the thread is interrupted.public static void alert()
isAlert(Throwable)