Skip to content

Instantly share code, notes, and snippets.

@ChristianSchwarz
Last active July 15, 2025 13:50
Show Gist options
  • Select an option

  • Save ChristianSchwarz/2dbe3e2a15572b3927735569d2a35704 to your computer and use it in GitHub Desktop.

Select an option

Save ChristianSchwarz/2dbe3e2a15572b3927735569d2a35704 to your computer and use it in GitHub Desktop.
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