/* * Copyright 1999-2011 Alibaba Group. * * 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 com.alibaba.dubbo.common.utils; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import com.alibaba.dubbo.common.Constants; import com.alibaba.dubbo.common.URL; import com.alibaba.dubbo.common.logger.Logger; import com.alibaba.dubbo.common.logger.LoggerFactory; /** * @author chao.liuc * */ public class ExecutorUtil { private static final Logger logger = LoggerFactory.getLogger(ExecutorUtil.class); private static final ThreadPoolExecutor shutdownExecutor = new ThreadPoolExecutor(0, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(100), new NamedThreadFactory("Close-ExecutorService-Timer", true)); public static boolean isShutdown(Executor executor) { if (executor instanceof ExecutorService) { if (((ExecutorService) executor).isShutdown()) { return true; } } return false; } public static void gracefulShutdown(Executor executor, int timeout) { if (!(executor instanceof ExecutorService) || isShutdown(executor)) { return; } final ExecutorService es = (ExecutorService) executor; try { es.shutdown(); // Disable new tasks from being submitted } catch (SecurityException ex2) { return ; } catch (NullPointerException ex2) { return ; } try { if(! es.awaitTermination(timeout, TimeUnit.MILLISECONDS)) { es.shutdownNow(); } } catch (InterruptedException ex) { es.shutdownNow(); Thread.currentThread().interrupt(); } if (!isShutdown(es)){ newThreadToCloseExecutor(es); } } public static void shutdownNow(Executor executor, final int timeout) { if (!(executor instanceof ExecutorService) || isShutdown(executor)) { return; } final ExecutorService es = (ExecutorService) executor; try { es.shutdownNow(); } catch (SecurityException ex2) { return ; } catch (NullPointerException ex2) { return ; } try { es.awaitTermination(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException ex) { Thread.currentThread().interrupt(); } if (!isShutdown(es)){ newThreadToCloseExecutor(es); } } private static void newThreadToCloseExecutor(final ExecutorService es) { if (!isShutdown(es)) { shutdownExecutor.execute(new Runnable() { public void run() { try { for (int i=0;i<1000;i++){ es.shutdownNow(); if (es.awaitTermination(10, TimeUnit.MILLISECONDS)){ break; } } } catch (InterruptedException ex) { Thread.currentThread().interrupt(); } catch (Throwable e) { logger.warn(e.getMessage(), e); } } }); } } /** * append thread name with url address * @return new url with updated thread name */ public static URL setThreadName(URL url, String defaultName) { String name = url.getParameter(Constants.THREAD_NAME_KEY, defaultName); name = new StringBuilder(32).append(name).append("-").append(url.getAddress()).toString(); url = url.addParameter(Constants.THREAD_NAME_KEY, name); return url; } }