1 /* 2 * Copyright 2009 Red Hat, Inc. 3 * 4 * Red Hat licenses this file to you under the Apache License, version 2.0 5 * (the "License"); you may not use this file except in compliance with the 6 * License. You may obtain a copy of the License at: 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations 14 * under the License. 15 */ 16 package org.jboss.netty.util.internal; 17 18 import java.util.concurrent.Executor; 19 import java.util.concurrent.ExecutorService; 20 import java.util.concurrent.TimeUnit; 21 22 /** 23 * Shuts down a list of {@link Executor}s. {@link #terminate(Executor...)} will 24 * shut down all specified {@link ExecutorService}s immediately and wait for 25 * their termination. An {@link Executor} which is not an {@link ExecutorService} 26 * will be ignored silently. 27 * 28 * @author <a href="http://www.jboss.org/netty/">The Netty Project</a> 29 * @author <a href="http://gleamynode.net/">Trustin Lee</a> 30 * @version $Rev: 2080 $, $Date: 2010-01-26 18:04:19 +0900 (Tue, 26 Jan 2010) $ 31 */ 32 public class ExecutorUtil { 33 34 /** 35 * Returns {@code true} if and only if the specified {@code executor} 36 * is an {@link ExecutorService} and is shut down. Please note that this 37 * method returns {@code false} if the specified {@code executor} is not an 38 * {@link ExecutorService}. 39 */ 40 public static boolean isShutdown(Executor executor) { 41 if (executor instanceof ExecutorService) { 42 if (((ExecutorService) executor).isShutdown()) { 43 return true; 44 } 45 } 46 return false; 47 } 48 49 /** 50 * Shuts down the specified executors. 51 */ 52 public static void terminate(Executor... executors) { 53 Executor[] executorsCopy = new Executor[executors.length]; 54 for (int i = 0; i < executors.length; i ++) { 55 if (executors[i] == null) { 56 throw new NullPointerException("executors[" + i + "]"); 57 } 58 executorsCopy[i] = executors[i]; 59 } 60 61 boolean interrupted = false; 62 for (Executor e: executorsCopy) { 63 if (!(e instanceof ExecutorService)) { 64 continue; 65 } 66 67 ExecutorService es = (ExecutorService) e; 68 for (;;) { 69 try { 70 es.shutdownNow(); 71 } catch (SecurityException ex) { 72 // Running in a restricted environment - fall back. 73 try { 74 es.shutdown(); 75 } catch (SecurityException ex2) { 76 // Running in a more restricted environment. 77 // Can't shut down this executor - skip to the next. 78 break; 79 } catch (NullPointerException ex2) { 80 // Some JDK throws NPE here, but shouldn't. 81 } 82 } catch (NullPointerException ex) { 83 // Some JDK throws NPE here, but shouldn't. 84 } 85 86 try { 87 if (es.awaitTermination(100, TimeUnit.MILLISECONDS)) { 88 break; 89 } 90 } catch (InterruptedException ex) { 91 interrupted = true; 92 } 93 } 94 } 95 96 if (interrupted) { 97 Thread.currentThread().interrupt(); 98 } 99 } 100 101 private ExecutorUtil() { 102 super(); 103 } 104 }