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