001/** 002 * Logback: the reliable, generic, fast and flexible logging framework. Copyright (C) 1999-2015, QOS.ch. All rights 003 * reserved. 004 * 005 * This program and the accompanying materials are dual-licensed under either the terms of the Eclipse Public License 006 * v1.0 as published by the Eclipse Foundation 007 * 008 * or (per the licensee's choosing) 009 * 010 * under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. 011 */ 012package ch.qos.logback.core.util; 013 014import java.lang.reflect.InvocationTargetException; 015import java.lang.reflect.Method; 016import java.util.concurrent.*; 017import java.util.concurrent.atomic.AtomicInteger; 018 019import ch.qos.logback.core.CoreConstants; 020 021/** 022 * Static utility methods for manipulating an {@link ExecutorService}. 023 * 024 * @author Carl Harris 025 * @author Mikhail Mazursky 026 */ 027public class ExecutorServiceUtil { 028 029 private static final ThreadFactory THREAD_FACTORY_FOR_SCHEDULED_EXECUTION_SERVICE = new ThreadFactory() { 030 031 private final AtomicInteger threadNumber = new AtomicInteger(1); 032 033 private final ThreadFactory defaultFactory = makeThreadFactory(); 034 035 /** 036 * A thread factory which may be a virtual thread factory the JDK supports it. 037 * 038 * @return 039 */ 040 private ThreadFactory makeThreadFactory() { 041 return Executors.defaultThreadFactory(); 042 } 043 044 @Override 045 public Thread newThread(Runnable r) { 046 Thread thread = defaultFactory.newThread(r); 047 if (!thread.isDaemon()) { 048 thread.setDaemon(true); 049 } 050 thread.setName("logback-" + threadNumber.getAndIncrement()); 051 return thread; 052 } 053 }; 054 055 static public ScheduledExecutorService newScheduledExecutorService() { 056 return new ScheduledThreadPoolExecutor(CoreConstants.SCHEDULED_EXECUTOR_POOL_SIZE, THREAD_FACTORY_FOR_SCHEDULED_EXECUTION_SERVICE); 057 } 058 059 /** 060 * @deprecated replaced by {@link #newThreadPoolExecutor()} 061 */ 062 static public ExecutorService newExecutorService() { 063 return newThreadPoolExecutor(); 064 } 065 066 /** 067 * Creates an ThreadPoolExecutor suitable for use by logback components. 068 * 069 * @since 1.4.7 070 * @return ThreadPoolExecutor 071 */ 072 static public ThreadPoolExecutor newThreadPoolExecutor() { 073 074 // irrelevant parameter when LinkedBlockingQueue is in use 075 final int maximumPoolSize = CoreConstants.CORE_POOL_SIZE + 1; 076 final long keepAliveMillis = 100L; 077 078 // As of version 1.5.13, the SynchronousQueue was replaced by LinkedBlockingQueue 079 // This has the effect of queueing jobs immediately and have them run by CORE_POOL_SIZE 080 // threads. We expect jobs to arrive at a relatively slow pace compared to their duration. 081 // Note that threads are removed if idle more than keepAliveMillis 082 ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(CoreConstants.CORE_POOL_SIZE, maximumPoolSize, keepAliveMillis, TimeUnit.MILLISECONDS, 083 new LinkedBlockingQueue<>(), THREAD_FACTORY_FOR_SCHEDULED_EXECUTION_SERVICE); 084 threadPoolExecutor.allowCoreThreadTimeOut(true); 085 return threadPoolExecutor; 086 087 } 088 089 /** 090 * Shuts down an executor service. 091 * <p> 092 * 093 * @param executorService the executor service to shut down 094 */ 095 static public void shutdown(ExecutorService executorService) { 096 if (executorService != null) { 097 executorService.shutdownNow(); 098 } 099 } 100 101 /** 102 * An alternate implementation of {@linl #newThreadPoolExecutor} which returns a virtual thread per task executor when 103 * available. 104 * 105 * @since 1.3.12/1.4.12 106 */ 107 static public ExecutorService newAlternateThreadPoolExecutor() { 108 return newThreadPoolExecutor(); 109 } 110}