Last active
July 15, 2025 13:50
-
-
Save ChristianSchwarz/2dbe3e2a15572b3927735569d2a35704 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package org; | |
| import static java.lang.Math.min; | |
| import static java.util.concurrent.TimeUnit.MILLISECONDS; | |
| import java.util.concurrent.ArrayBlockingQueue; | |
| import java.util.concurrent.BlockingQueue; | |
| import java.util.concurrent.TimeUnit; | |
| import java.util.concurrent.locks.LockSupport; | |
| public class Sleeper { | |
| private static final long SLEEP_PRECISION = TimeUnit.MILLISECONDS.toNanos(2); | |
| private static final long SPIN_YIELD_PRECISION = TimeUnit.MILLISECONDS.toNanos(2); | |
| public static void main(String... args) throws Exception { | |
| Thread.currentThread().setPriority(Thread.MIN_PRIORITY); | |
| System.out.println("Blocking Queue"); | |
| final BlockingQueue<?> SLEEPER = new ArrayBlockingQueue<>(1); | |
| run(() -> SLEEPER.poll(20, MILLISECONDS)); | |
| System.out.println("Thread.sleep"); | |
| run(() -> TimeUnit.MILLISECONDS.sleep(20)); | |
| System.out.println("sleepNanos"); | |
| run(() -> sleepNanos(20000000)); | |
| System.out.println("parkNanos"); | |
| run(() -> LockSupport.parkNanos(20000000)); | |
| System.out.println("burn"); | |
| run(() -> { | |
| long deadline = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(20); | |
| while (System.nanoTime() < deadline) { | |
| } | |
| }); | |
| } | |
| private static void run(final Task task) throws Exception { | |
| long[] l = new long[100]; | |
| long min = Long.MAX_VALUE, max = Long.MIN_VALUE; | |
| for (int i = 0; i < 100; i++) { | |
| long start = System.nanoTime(); | |
| task.call(); | |
| long time = System.nanoTime() - start; | |
| min = min(time, min); | |
| max = Math.max(time, max); | |
| l[i] = time; | |
| } | |
| long avr = avr(l); | |
| System.out.printf("Min %5.1f%n", (min / 1e6) - 20); | |
| System.out.printf("Max %5.1f%n", (max / 1e6) - 20); | |
| System.out.printf("Avr %5.1f%n", (avr / 1e6) - 20); | |
| } | |
| private static long avr(long[] l) { | |
| long sum = 0; | |
| for (long m : l) { | |
| sum += m; | |
| } | |
| return sum / l.length; | |
| } | |
| interface Task { | |
| void call() throws Exception; | |
| } | |
| /* | |
| * Spin-yield loop based alternative to Thread.sleep Based on the code of | |
| * Andy Malakov | |
| * http://andy-malakov.blogspot.fr/2010/06/alternative-to-threadsleep.html | |
| */ | |
| public static void sleepNanos(long nanoDuration) throws InterruptedException { | |
| final long end = System.nanoTime() + nanoDuration; | |
| long timeLeft = nanoDuration; | |
| do { | |
| if (timeLeft > SLEEP_PRECISION) { | |
| Thread.sleep(1); | |
| } else { | |
| if (timeLeft > SPIN_YIELD_PRECISION) { | |
| Thread.yield(); | |
| } | |
| } | |
| timeLeft = end - System.nanoTime(); | |
| if (Thread.interrupted()) | |
| throw new InterruptedException(); | |
| } while (timeLeft > 0); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment