Infrasctructural costs of Thread.sleep() vs LockSupport.parkNanos()

Viewed 89

While running the following benchmark on Java 11 (Linux and MacOS):

@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public class ThreadSleepVsParkNanosBenchmark {

  @Benchmark
  public void sleep1ms() throws Exception {
    Thread.sleep(1);
  }

  @Benchmark
  public void parkNanos1ms() {
    LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(1));
  }

  @Benchmark
  public void parkNanos500us() {
    LockSupport.parkNanos(TimeUnit.MICROSECONDS.toNanos(500));
  }

  @Benchmark
  public void parkNanos100us() {
    LockSupport.parkNanos(TimeUnit.MICROSECONDS.toNanos(100));
  }
}

I've found out that the costs of running Thread.sleep(1) and LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(1)) i.e. the overhead of suspending and revoking the thread are pretty much the same on both platforms. But the overhead of LockSupport.parkNanos(TimeUnit.MICROSECONDS.toNanos(100)) is significantly lower:

Linux
Benchmark                                                 Mode  Cnt        Score      Error  Units
ThreadSleepVsParkNanosBenchmark.parkNanos100us            avgt  100      159.775 ±    0.248  us/op
ThreadSleepVsParkNanosBenchmark.parkNanos500us            avgt  100      612.971 ±    0.578  us/op
ThreadSleepVsParkNanosBenchmark.parkNanos1ms              avgt  100     1103.372 ±    4.685  us/op
ThreadSleepVsParkNanosBenchmark.sleep1ms                  avgt  100     1119.566 ±    0.940  us/op

MacOS
ThreadSleepVsParkNanosBenchmark.parkNanos100us            avgt  100      156,696 ±     6,977  us/op
ThreadSleepVsParkNanosBenchmark.parkNanos500us            avgt  100      752,520 ±    23,203  us/op
ThreadSleepVsParkNanosBenchmark.parkNanos1ms              avgt  100     1508,832 ±     7,580  us/op
ThreadSleepVsParkNanosBenchmark.sleep1ms                  avgt  100     1430,396 ±    32,876  us/op

What is the explanation? As far as it comes from the JavaDoc both Thread.sleep() and LockSupport.parkNanos() put the thread into Thread.State.TIMED_WAITING, so the mechanism under the hood must be the same along with the costs.

0 Answers
Related