package greenfoot.util;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
| Timer to do high precision sleeps and waits.
|
| @author Poul Henriksen
|
public class HDTimer
{
private static Long sleepPrecision;
private static long worstYieldTime;
private static boolean inited;
private static Long waitPrecision;
static {
init();
}
public synchronized static void init()
{
if (!inited) {
measureSleepPrecision();
measureWaitPrecision();
inited = true;
}
}
private static void measureSleepPrecision()
{
int testSize = 11;
List<Long> tests = new ArrayList<Long>();
try {
for (int i = 0; i < testSize; i++) {
long t1 = System.nanoTime();
Thread.sleep(0, 1);
long t2 = System.nanoTime();
tests.add((t2 - t1));
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
Collections.sort(tests);
sleepPrecision = tests.get(testSize / 2);
}
private static void measureWaitPrecision()
{
int testSize = 11;
List<Long> tests = new ArrayList<Long>();
Object lock = new Object();
try {
synchronized (lock) {
for (int i = 0; i < testSize; i++) {
long t1 = System.nanoTime();
lock.wait(0, 1);
long t2 = System.nanoTime();
tests.add((t2 - t1));
}
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
Collections.sort(tests);
waitPrecision = tests.get(testSize / 2);
}
| Sleep for the specified amount of time.
|
| @param nanos
| Time to wait in nanoseconds.
| @throws InterruptedException
| if another thread has interrupted the current thread
|
public static void sleep(long nanos)
throws InterruptedException
{
long tStart = System.nanoTime();
sleepFromTime(nanos, tStart);
}
| Sleep for the specified amount of time.
|
| @param nanos
| Time to wait in nanoseconds.
| @param tStart The tiem from which the wainting should start.
|
| @throws InterruptedException
| if another thread has interrupted the current thread
|
private static void sleepFromTime(long nanos, long tStart)
throws InterruptedException
{
long sleepNanos = nanos - sleepPrecision;
if (nanos / sleepPrecision >= 2) {
long actualDelayMillis = (sleepNanos) / 1000000L;
int nanoRest = (int) (sleepNanos % 1000000L);
if (Thread.interrupted()) {
throw new InterruptedException("HDTimer.sleepFromTime interrupted in sleep.");
}
Thread.sleep(actualDelayMillis, nanoRest);
}
while ((System.nanoTime() - tStart + worstYieldTime) < nanos){
long t1 = System.nanoTime();
if (Thread.interrupted()) {
throw new InterruptedException("HDTimer.sleepFromTime interrupted in yield.");
}
Thread.yield();
long yieldTime = System.nanoTime() - t1;
if (yieldTime > worstYieldTime) {
worstYieldTime = yieldTime;
}
}
while ((System.nanoTime() - tStart) < nanos){
if (Thread.interrupted()) {
throw new InterruptedException("HDTimer.sleepFromTime interrupted in busy loop.");
}
}
}
}
top,
use,
map,
class HDTimer
. init
. measureSleepPrecision
. measureWaitPrecision
. sleep
. sleepFromTime
148 neLoCode
+ 13 LoComm