this implementation of Delayed
is good because:
- implementation of
compareTo()
does not do any class casting, eliminatig the possibility of throwing a ClassCastException
- implementation of
compareTo()
uses Math.min
and Math.max
functions before casting to int
in order to properly prevent overflow errors
- implementation of
getDelay()
properly converts the units and actually returns the time remaining
TestDelay
class implements Delayed
:
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
public class TestDelay implements Delayed
{
public final Long delayMillis;
public final Long expireTimeMillis;
public TestDelay(Long delayMillis)
{
this.delayMillis = delayMillis;
this.expireTimeMillis = System.currentTimeMillis()+delayMillis;
}
@Override
public final int compareTo(@NotNull Delayed o)
{
long diffMillis = getDelay(TimeUnit.MILLISECONDS)-o.getDelay(TimeUnit.MILLISECONDS);
diffMillis = Math.min(diffMillis,1);
diffMillis = Math.max(diffMillis,-1);
return (int) diffMillis;
}
@Override
public final long getDelay(@NotNull TimeUnit unit)
{
long delayMillis = expireTimeMillis-System.currentTimeMillis();
return unit.convert(delayMillis,TimeUnit.MILLISECONDS);
}
}
JUnit unit test showing an example of using the TestDelay
class:
import org.junit.Test;
import java.util.concurrent.DelayQueue;
public class DelayQueueTest
{
@Test
public final void generalTest() throws InterruptedException
{
DelayQueue<TestDelay> q = new DelayQueue<>();
q.put(new TestDelay(500L));
q.put(new TestDelay(2000L));
q.put(new TestDelay(1000L));
q.put(new TestDelay(10L));
q.put(new TestDelay(3000L));
while (!q.isEmpty())
{
System.out.println(q.take().delayMillis);
}
}
}
output of DelayQueueTest
:
