All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.cometd.benchmark.MonitoringQueuedThreadPool Maven / Gradle / Ivy

There is a newer version: 7.0.17
Show newest version
/*
 * Copyright (c) 2008-2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.cometd.benchmark;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

import org.eclipse.jetty.util.BlockingArrayQueue;
import org.eclipse.jetty.util.thread.QueuedThreadPool;

public class MonitoringQueuedThreadPool extends QueuedThreadPool {
    private final AtomicLong tasks = new AtomicLong();
    private final AtomicLong maxTaskLatency = new AtomicLong();
    private final AtomicLong totalTaskLatency = new AtomicLong();
    private final MonitoringBlockingArrayQueue queue;
    private final AtomicLong maxQueueLatency = new AtomicLong();
    private final AtomicLong totalQueueLatency = new AtomicLong();
    private final AtomicInteger threads = new AtomicInteger();
    private final AtomicInteger maxThreads = new AtomicInteger();

    public MonitoringQueuedThreadPool(int maxThreads) {
        // Use a very long idle timeout to avoid creation/destruction of threads
        super(maxThreads, maxThreads, 24 * 3600 * 1000, new MonitoringBlockingArrayQueue(maxThreads, 256));
        queue = (MonitoringBlockingArrayQueue)getQueue();
        setStopTimeout(2000);
    }

    @Override
    public void execute(final Runnable job) {
        final long begin = System.nanoTime();
        super.execute(new Runnable() {
            public void run() {
                long queueLatency = System.nanoTime() - begin;
                tasks.incrementAndGet();
                Atomics.updateMax(maxQueueLatency, queueLatency);
                totalQueueLatency.addAndGet(queueLatency);
                Atomics.updateMax(maxThreads, threads.incrementAndGet());
                long start = System.nanoTime();
                try {
                    job.run();
                } finally {
                    long taskLatency = System.nanoTime() - start;
                    threads.decrementAndGet();
                    Atomics.updateMax(maxTaskLatency, taskLatency);
                    totalTaskLatency.addAndGet(taskLatency);
                }
            }
        });
    }

    public void reset() {
        tasks.set(0);
        maxTaskLatency.set(0);
        totalTaskLatency.set(0);
        queue.reset();
        maxQueueLatency.set(0);
        totalQueueLatency.set(0);
        threads.set(0);
        maxThreads.set(0);
    }

    public long getTasks() {
        return tasks.get();
    }

    public int getMaxActiveThreads() {
        return maxThreads.get();
    }

    public int getMaxQueueSize() {
        return queue.maxSize.get();
    }

    public long getAverageQueueLatency() {
        long count = tasks.get();
        return count == 0 ? -1 : totalQueueLatency.get() / count;
    }

    public long getMaxQueueLatency() {
        return maxQueueLatency.get();
    }

    public long getMaxTaskLatency() {
        return maxTaskLatency.get();
    }

    public long getAverageTaskLatency() {
        long count = tasks.get();
        return count == 0 ? -1 : totalTaskLatency.get() / count;
    }

    public static class MonitoringBlockingArrayQueue extends BlockingArrayQueue {
        private final AtomicInteger size = new AtomicInteger();
        private final AtomicInteger maxSize = new AtomicInteger();

        public MonitoringBlockingArrayQueue(int capacity, int growBy) {
            super(capacity, growBy);
        }

        public void reset() {
            size.set(0);
            maxSize.set(0);
        }

        @Override
        public void clear() {
            reset();
            super.clear();
        }

        @Override
        public boolean offer(Runnable job) {
            boolean added = super.offer(job);
            if (added) {
                increment();
            }
            return added;
        }

        private void increment() {
            Atomics.updateMax(maxSize, size.incrementAndGet());
        }

        @Override
        public Runnable poll() {
            Runnable job = super.poll();
            if (job != null) {
                decrement();
            }
            return job;
        }

        @Override
        public Runnable poll(long time, TimeUnit unit) throws InterruptedException {
            Runnable job = super.poll(time, unit);
            if (job != null) {
                decrement();
            }
            return job;
        }

        @Override
        public Runnable take() throws InterruptedException {
            Runnable job = super.take();
            decrement();
            return job;
        }

        private void decrement() {
            size.decrementAndGet();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy