diff --git a/metrics-core/src/main/java/com/codahale/metrics/ExponentiallyDecayingReservoir.java b/metrics-core/src/main/java/com/codahale/metrics/ExponentiallyDecayingReservoir.java index 7ff16ded5c..c8c6b0f317 100644 --- a/metrics-core/src/main/java/com/codahale/metrics/ExponentiallyDecayingReservoir.java +++ b/metrics-core/src/main/java/com/codahale/metrics/ExponentiallyDecayingReservoir.java @@ -95,7 +95,7 @@ public void update(long value, long timestamp) { try { final double itemWeight = weight(timestamp - startTime); final WeightedSample sample = new WeightedSample(value, itemWeight); - final double priority = itemWeight / ThreadLocalRandom.current().nextDouble(); + final double priority = itemWeight / ThreadLocalRandomProxy.current().nextDouble(); final long newCount = count.incrementAndGet(); if (newCount <= size) { diff --git a/metrics-core/src/main/java/com/codahale/metrics/ThreadLocalRandomProxy.java b/metrics-core/src/main/java/com/codahale/metrics/ThreadLocalRandomProxy.java new file mode 100644 index 0000000000..54deaee50a --- /dev/null +++ b/metrics-core/src/main/java/com/codahale/metrics/ThreadLocalRandomProxy.java @@ -0,0 +1,37 @@ +package com.codahale.metrics; + +import java.util.Random; + +/** + * Proxy for creating thread local {@link Random} instances depending on the runtime. + * By default it tries to use the JDK's implementation and fallbacks to the internal + * one if the JDK doesn't provide any. + */ +class ThreadLocalRandomProxy { + + /** + * To avoid NoClassDefFoundError during loading {@link ThreadLocalRandomProxy} + */ + private static class JdkDelegate { + + private static Random current() { + return java.util.concurrent.ThreadLocalRandom.current(); + } + } + + private static final boolean IS_JDK_THREAD_LOCAL_AVAILABLE = isIsJdkThreadLocalAvailable(); + + private static boolean isIsJdkThreadLocalAvailable() { + try { + JdkDelegate.current(); + return true; + } catch (NoClassDefFoundError e) { + return false; + } + } + + public static Random current() { + return IS_JDK_THREAD_LOCAL_AVAILABLE ? JdkDelegate.current() : ThreadLocalRandom.current(); + } + +} diff --git a/metrics-core/src/main/java/com/codahale/metrics/UniformReservoir.java b/metrics-core/src/main/java/com/codahale/metrics/UniformReservoir.java index d9812531d8..5e816b42e9 100644 --- a/metrics-core/src/main/java/com/codahale/metrics/UniformReservoir.java +++ b/metrics-core/src/main/java/com/codahale/metrics/UniformReservoir.java @@ -70,7 +70,7 @@ public void update(long value) { private static long nextLong(long n) { long bits, val; do { - bits = ThreadLocalRandom.current().nextLong() & (~(1L << BITS_PER_LONG)); + bits = ThreadLocalRandomProxy.current().nextLong() & (~(1L << BITS_PER_LONG)); val = bits % n; } while (bits - val + (n - 1) < 0L); return val;