Code cleanup and improved toString() and javadocs.
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
This commit is contained in:
parent
7bb1adb798
commit
d2e13ec5ad
|
@ -33,6 +33,20 @@ import static java.lang.Long.MAX_VALUE;
|
||||||
* <p>Subclasses should implement {@link #onTimeoutExpired()}.</p>
|
* <p>Subclasses should implement {@link #onTimeoutExpired()}.</p>
|
||||||
* <p>This implementation is optimised assuming that the timeout
|
* <p>This implementation is optimised assuming that the timeout
|
||||||
* will mostly be cancelled and then reused with a similar value.</p>
|
* will mostly be cancelled and then reused with a similar value.</p>
|
||||||
|
* <p>This implementation has a {@link Timeout} holding the time
|
||||||
|
* at which the scheduled task should fire, and a linked list of
|
||||||
|
* {@link Wakeup}, each holding the actual scheduled task.</p>
|
||||||
|
* <p>Calling {@link #schedule(long, TimeUnit)} the first time will
|
||||||
|
* create a Timeout with an associated Wakeup and submit a task to
|
||||||
|
* the scheduler.
|
||||||
|
* Calling {@link #schedule(long, TimeUnit)} again with the same or
|
||||||
|
* a larger delay will cancel the previous Timeout, but keep the
|
||||||
|
* previous Wakeup without submitting a new task to the scheduler,
|
||||||
|
* therefore reducing the pressure on the scheduler and avoid it
|
||||||
|
* becomes a bottleneck.
|
||||||
|
* When the Wakeup task fires, it will see that the Timeout is now
|
||||||
|
* in the future and will attach a new Wakeup with the future time
|
||||||
|
* to the Timeout, and submit a scheduler task for the new Wakeup.</p>
|
||||||
*/
|
*/
|
||||||
public abstract class CyclicTimeout implements Destroyable
|
public abstract class CyclicTimeout implements Destroyable
|
||||||
{
|
{
|
||||||
|
@ -59,24 +73,24 @@ public abstract class CyclicTimeout implements Destroyable
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Schedules a timeout, even if already set, cancelled or expired.
|
* <p>Schedules a timeout, even if already set, cancelled or expired.</p>
|
||||||
|
* <p>If a timeout is already set, it will be cancelled and replaced
|
||||||
|
* by the new one.</p>
|
||||||
*
|
*
|
||||||
* @param delay The period of time before the timeout expires.
|
* @param delay The period of time before the timeout expires.
|
||||||
* @param units The unit of time of the period.
|
* @param units The unit of time of the period.
|
||||||
* @return true if the timer was already set.
|
* @return true if the timeout was already set.
|
||||||
*/
|
*/
|
||||||
public boolean schedule(long delay, TimeUnit units)
|
public boolean schedule(long delay, TimeUnit units)
|
||||||
{
|
{
|
||||||
long now = System.nanoTime();
|
long now = System.nanoTime();
|
||||||
long new_timeout_at = now + units.toNanos(delay);
|
long new_timeout_at = now + units.toNanos(delay);
|
||||||
|
|
||||||
|
Wakeup new_wakeup = null;
|
||||||
boolean result;
|
boolean result;
|
||||||
Wakeup new_wakeup;
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
Timeout timeout = _timeout.get();
|
Timeout timeout = _timeout.get();
|
||||||
|
|
||||||
new_wakeup = null;
|
|
||||||
result = timeout._at != MAX_VALUE;
|
result = timeout._at != MAX_VALUE;
|
||||||
|
|
||||||
// Is the current wakeup good to use? ie before our timeout time?
|
// Is the current wakeup good to use? ie before our timeout time?
|
||||||
|
@ -114,14 +128,12 @@ public abstract class CyclicTimeout implements Destroyable
|
||||||
public boolean cancel()
|
public boolean cancel()
|
||||||
{
|
{
|
||||||
boolean result;
|
boolean result;
|
||||||
Timeout timeout;
|
|
||||||
Timeout new_timeout;
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
timeout = _timeout.get();
|
Timeout timeout = _timeout.get();
|
||||||
result = timeout._at != MAX_VALUE;
|
result = timeout._at != MAX_VALUE;
|
||||||
Wakeup wakeup = timeout._wakeup;
|
Wakeup wakeup = timeout._wakeup;
|
||||||
new_timeout = wakeup == null ? NOT_SET : new Timeout(MAX_VALUE, wakeup);
|
Timeout new_timeout = wakeup == null ? NOT_SET : new Timeout(MAX_VALUE, wakeup);
|
||||||
if (_timeout.compareAndSet(timeout, new_timeout))
|
if (_timeout.compareAndSet(timeout, new_timeout))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -166,7 +178,11 @@ public abstract class CyclicTimeout implements Destroyable
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return String.format("%s@%x:%d,%s", getClass().getSimpleName(), hashCode(), _at, _wakeup);
|
return String.format("%s@%x:%dms,%s",
|
||||||
|
getClass().getSimpleName(),
|
||||||
|
hashCode(),
|
||||||
|
TimeUnit.NANOSECONDS.toMillis(_at - System.nanoTime()),
|
||||||
|
_wakeup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,10 +216,9 @@ public abstract class CyclicTimeout implements Destroyable
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
long now;
|
long now = System.nanoTime();
|
||||||
Wakeup new_wakeup;
|
Wakeup new_wakeup = null;
|
||||||
boolean has_expired;
|
boolean has_expired = false;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
Timeout timeout = _timeout.get();
|
Timeout timeout = _timeout.get();
|
||||||
|
@ -226,16 +241,12 @@ public abstract class CyclicTimeout implements Destroyable
|
||||||
// Not found, we become a noop.
|
// Not found, we become a noop.
|
||||||
return;
|
return;
|
||||||
|
|
||||||
now = System.nanoTime();
|
|
||||||
new_wakeup = null;
|
|
||||||
has_expired = false;
|
|
||||||
Timeout new_timeout;
|
|
||||||
|
|
||||||
// We are in the wakeup list! So we have to act and we know our
|
// We are in the wakeup list! So we have to act and we know our
|
||||||
// tail has not expired (else it would have removed us from the list).
|
// tail has not expired (else it would have removed us from the list).
|
||||||
// Remove ourselves (and any prior Wakeup) from the wakeup list.
|
// Remove ourselves (and any prior Wakeup) from the wakeup list.
|
||||||
wakeup = wakeup._next;
|
wakeup = wakeup._next;
|
||||||
|
|
||||||
|
Timeout new_timeout;
|
||||||
if (timeout._at <= now)
|
if (timeout._at <= now)
|
||||||
{
|
{
|
||||||
// We have timed out!
|
// We have timed out!
|
||||||
|
@ -274,7 +285,11 @@ public abstract class CyclicTimeout implements Destroyable
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return String.format("%s@%x:%d->%s", getClass().getSimpleName(), hashCode(), _at, _next);
|
return String.format("%s@%x:%dms->%s",
|
||||||
|
getClass().getSimpleName(),
|
||||||
|
hashCode(),
|
||||||
|
_at == MAX_VALUE ? _at : TimeUnit.NANOSECONDS.toMillis(_at - System.nanoTime()),
|
||||||
|
_next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue