class InstrumentedQueuedThreadPool extends QueuedThreadPool {

    @Override
    protected void doStart() throws Exception {
        super.doStart();

        final String prefix = this.prefix == null ? name(QueuedThreadPool.class, getName()) : name(this.prefix, getName());

        metricRegistry.register(name(prefix, "utilization"), new RatioGauge() {
            @Override
            protected Ratio getRatio() {
                return Ratio.of(getThreads() - getIdleThreads(), getThreads());
            }
        });
        metricRegistry.register(name(prefix, "utilization-max"), new RatioGauge() {
            @Override
            protected Ratio getRatio() {
                return Ratio.of(getThreads() - getIdleThreads(), getMaxThreads());
            }
        });
        metricRegistry.register(name(prefix, "size"), (Gauge<Integer>) this::getThreads);
        metricRegistry.register(name(prefix, "jobs"), (Gauge<Integer>) () -> {
            // This assumes the QueuedThreadPool is using a BlockingArrayQueue or
            // ArrayBlockingQueue for its queue, and is therefore a constant-time operation.
            return getQueue().size();
        });
        metricRegistry.register(name(prefix, "jobs-queue-utilization"), new RatioGauge() {
            @Override
            protected Ratio getRatio() {
                BlockingQueue<Runnable> queue = getQueue();
                return Ratio.of(queue.size(), queue.size() + queue.remainingCapacity());
            }
        });
    }

    public  InstrumentedQueuedThreadPool(@Name("registry") MetricRegistry registry);
    public  InstrumentedQueuedThreadPool(@Name("registry") MetricRegistry registry,
                                        @Name("maxThreads") int maxThreads);
    public  InstrumentedQueuedThreadPool(@Name("registry") MetricRegistry registry,
                                        @Name("maxThreads") int maxThreads,
                                        @Name("minThreads") int minThreads);
    public  InstrumentedQueuedThreadPool(@Name("registry") MetricRegistry registry,
                                        @Name("maxThreads") int maxThreads,
                                        @Name("minThreads") int minThreads,
                                        @Name("idleTimeout") int idleTimeout);
    public  InstrumentedQueuedThreadPool(@Name("registry") MetricRegistry registry,
                                        @Name("maxThreads") int maxThreads,
                                        @Name("minThreads") int minThreads,
                                        @Name("idleTimeout") int idleTimeout,
                                        @Name("queue") BlockingQueue<Runnable> queue);
    public  InstrumentedQueuedThreadPool(@Name("registry") MetricRegistry registry,
                                        @Name("maxThreads") int maxThreads,
                                        @Name("minThreads") int minThreads,
                                        @Name("idleTimeout") int idleTimeout,
                                        @Name("queue") BlockingQueue<Runnable> queue,
                                        @Name("prefix") String prefix);

}