diff --git a/src/main/java/com/zaxxer/hikari/util/Sequence.java b/src/main/java/com/zaxxer/hikari/util/Sequence.java index 29a07549..34152559 100644 --- a/src/main/java/com/zaxxer/hikari/util/Sequence.java +++ b/src/main/java/com/zaxxer/hikari/util/Sequence.java @@ -16,6 +16,9 @@ package com.zaxxer.hikari.util; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.LongAdder; @@ -44,21 +47,22 @@ public interface Sequence /** * Factory class used to create a platform-specific ClockSource. */ - class Factory + final class Factory { @SuppressWarnings("serial") public static Sequence create() { - class Java7Sequence extends AtomicLong implements Sequence { + final class Java7Sequence extends AtomicLong implements Sequence { Java7Sequence() { } + @Override public void increment() { this.incrementAndGet(); } } - class Java8Sequence extends LongAdder implements Sequence { + final class Java8Sequence extends LongAdder implements Sequence { public Java8Sequence() { } @@ -68,16 +72,59 @@ public interface Sequence } } - Sequence sequence = null; + final class DropwizardSequence implements Sequence { + private final Object longAdder; + private final Method increment; + private final Method sum; + + public DropwizardSequence(Class longAdderClass) throws Exception { + Constructor constructor = longAdderClass.getDeclaredConstructors()[0]; + constructor.setAccessible(true); + increment = longAdderClass.getMethod("increment"); + increment.setAccessible(true); + sum = longAdderClass.getMethod("sum"); + sum.setAccessible(true); + longAdder = constructor.newInstance(); + } + + @Override + public void increment() + { + try { + increment.invoke(longAdder); + } + catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + throw new RuntimeException(e); + } + } + + @Override + public long get() + { + try { + return (Long) sum.invoke(longAdder); + } + catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + throw new RuntimeException(e); + } + } + } + try { if (Sequence.class.getClassLoader().loadClass("java.util.concurrent.atomic.LongAdder") != null) { - sequence = new Java8Sequence(); + return new Java8Sequence(); } } catch (ClassNotFoundException e) { + try { + Class longAdderClass = Sequence.class.getClassLoader().loadClass("com.codahale.metrics.LongAdder"); + return new DropwizardSequence(longAdderClass); + } + catch (Exception e2) { + } } - return sequence != null ? sequence : new Java7Sequence(); + return new Java7Sequence(); } } }