Organize Imports to be Checkstyle compliant in utils
[yangtools.git] / common / util / src / main / java / org / opendaylight / yangtools / util / ExecutorServiceUtil.java
index 36f729fb8ff69210e475ad67f8466f3dd973f5f0..429bb0bd0c0e66ce33b49f6f619bdbb1e004c4ee 100644 (file)
@@ -7,17 +7,16 @@
  */
 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 org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.util.concurrent.ForwardingBlockingQueue;
-
 /**
  * Utility methods for dealing with {@link ExecutorService}s.
  */
@@ -25,11 +24,15 @@ 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("Intterupted while waiting for queue", e);
-                throw new RejectedExecutionException("Interrupted while waiting for queue", e);
+                LOG.debug("Interrupted while attempting to put to the queue", e);
+                throw new RejectedExecutionException("Interrupted while attempting to put to the queue", e);
             }
         }
     }
@@ -42,7 +45,7 @@ public final class ExecutorServiceUtil {
     }
 
     /**
-     * Create a {@link BlockingQueue} which does not allow for non-blocking addition to the queue.
+     * 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.
@@ -50,7 +53,7 @@ public final class ExecutorServiceUtil {
      * @param delegate Backing blocking queue.
      * @return A new blocking queue backed by the delegate
      */
-    public <E> BlockingQueue<E> offerFailingBlockingQueue(final BlockingQueue<E> delegate) {
+    public static <E> BlockingQueue<E> offerFailingBlockingQueue(final BlockingQueue<E> delegate) {
         return new ForwardingBlockingQueue<E>() {
             @Override
             public boolean offer(final E o) {
@@ -65,12 +68,31 @@ public final class ExecutorServiceUtil {
     }
 
     /**
-     * Return a {@link RejectedExecutionHandler} which blocks on the {@link ThreadPoolExecutor}'s
+     * 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 RejectedExecutionHandler waitInQueueExecutionHandler() {
+    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();
+        }
+    }
 }