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

org.zalando.riptide.concurrent.WorkQueue Maven / Gradle / Ivy

package org.zalando.riptide.concurrent;

import lombok.AllArgsConstructor;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * A special {@link BlockingQueue} that refuses to accept new elements
 * as long as no consumer is waiting.
 *
 * It deliberately breaks the {@link BlockingQueue} contract in order to
 * make any {@link ThreadPoolExecutor} using this queue start new threads
 * rather than adding tasks to the queue.
 *
 * Once the thread pool reaches it's {@link ThreadPoolExecutor#getMaximumPoolSize() maximum pool size}
 * it will then re-queue tasks using the {@link ReEnqueuePolicy}.
 *
 * @see Java Scale First ExecutorService — A myth or a reality
 * @see ReEnqueuePolicy
 * @param  element type
 */
@AllArgsConstructor
final class WorkQueue extends ForwardingBlockingQueue {

    private final AtomicInteger idleWorkers = new AtomicInteger();
    private final BlockingQueue delegate;

    @Override
    protected BlockingQueue delegate() {
        return delegate;
    }

    @Override
    public boolean offer(final E element) {
        if (idleWorkers.get() == 0) {
            return false;
        }

        return super.offer(element);
    }

    @Override
    public boolean add(final E element) {
        return super.offer(element);
    }

    @Override
    public E take() throws InterruptedException {
        idleWorkers.incrementAndGet();

        try {
            return super.take();
        } finally {
            idleWorkers.decrementAndGet();
        }
    }

    @Override
    public E poll(final long timeout, final TimeUnit unit)
            throws InterruptedException {

        idleWorkers.incrementAndGet();

        try {
            return super.poll(timeout, unit);
        } finally {
            idleWorkers.decrementAndGet();
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy