org.opendaylight.yangtools.util.ExecutorServiceUtil.java Source code

Java tutorial

Introduction

Here is the source code for org.opendaylight.yangtools.util.ExecutorServiceUtil.java

Source

/*
 * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */
package org.opendaylight.yangtools.util;

import com.google.common.util.concurrent.ForwardingBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Utility methods for dealing with {@link ExecutorService}s.
 */
public final class ExecutorServiceUtil {
    private static final class WaitInQueueExecutionHandler implements RejectedExecutionHandler {
        @Override
        public void rejectedExecution(final Runnable r, final ThreadPoolExecutor executor) {
            if (executor.isShutdown()) {
                throw new RejectedExecutionException("Executor has been shutdown.");
            }

            try {
                executor.getQueue().put(r);
            } catch (InterruptedException e) {
                LOG.debug("Interrupted while attempting to put to the queue", e);
                throw new RejectedExecutionException("Interrupted while attempting to put to the queue", e);
            }
        }
    }

    private static final Logger LOG = LoggerFactory.getLogger(ExecutorServiceUtil.class);
    private static final RejectedExecutionHandler WAIT_IN_QUEUE_HANDLER = new WaitInQueueExecutionHandler();

    private ExecutorServiceUtil() {
        throw new UnsupportedOperationException("Utility class");
    }

    /**
     * Creates a {@link BlockingQueue} which does not allow for non-blocking addition to the queue.
     * This is useful with {@link #waitInQueueExecutionHandler()} to turn force a
     * {@link ThreadPoolExecutor} to create as many threads as it is configured to before starting
     * to fill the queue.
     *
     * @param delegate Backing blocking queue.
     * @return A new blocking queue backed by the delegate
     */
    public static <E> BlockingQueue<E> offerFailingBlockingQueue(final BlockingQueue<E> delegate) {
        return new ForwardingBlockingQueue<E>() {
            @Override
            public boolean offer(@Nonnull final E o) {
                return false;
            }

            @Override
            protected BlockingQueue<E> delegate() {
                return delegate;
            }
        };
    }

    /**
     * Returns a {@link RejectedExecutionHandler} which blocks on the {@link ThreadPoolExecutor}'s
     * backing queue if a new thread cannot be spawned.
     *
     * @return A shared RejectedExecutionHandler instance.
     */
    public static RejectedExecutionHandler waitInQueueExecutionHandler() {
        return WAIT_IN_QUEUE_HANDLER;
    }

    /**
     * Tries to shutdown the given executor gracefully by awaiting termination for the given
     * timeout period. If the timeout elapses before termination, the executor is forcefully
     * shutdown.
     */
    public static void tryGracefulShutdown(final ExecutorService executor, long timeout, TimeUnit unit) {

        executor.shutdown();

        try {
            if (!executor.awaitTermination(timeout, unit)) {
                executor.shutdownNow();
            }
        } catch (InterruptedException e) {
            executor.shutdownNow();
        }
    }
}