1 /**
2 * Logback: the reliable, generic, fast and flexible logging framework. Copyright (C) 1999-2015, QOS.ch. All rights
3 * reserved.
4 *
5 * This program and the accompanying materials are dual-licensed under either the terms of the Eclipse Public License
6 * v1.0 as published by the Eclipse Foundation
7 *
8 * or (per the licensee's choosing)
9 *
10 * under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation.
11 */
12 package ch.qos.logback.core.util;
13
14 import java.lang.reflect.InvocationTargetException;
15 import java.lang.reflect.Method;
16 import java.util.concurrent.*;
17 import java.util.concurrent.atomic.AtomicInteger;
18
19 import ch.qos.logback.core.CoreConstants;
20
21 /**
22 * Static utility methods for manipulating an {@link ExecutorService}.
23 *
24 * @author Carl Harris
25 * @author Mikhail Mazursky
26 */
27 public class ExecutorServiceUtil {
28
29 private static final ThreadFactory THREAD_FACTORY_FOR_SCHEDULED_EXECUTION_SERVICE = new ThreadFactory() {
30
31 private final AtomicInteger threadNumber = new AtomicInteger(1);
32
33 private final ThreadFactory defaultFactory = makeThreadFactory();
34
35 /**
36 * A thread factory which may be a virtual thread factory the JDK supports it.
37 *
38 * @return
39 */
40 private ThreadFactory makeThreadFactory() {
41 return Executors.defaultThreadFactory();
42 }
43
44 @Override
45 public Thread newThread(Runnable r) {
46 Thread thread = defaultFactory.newThread(r);
47 if (!thread.isDaemon()) {
48 thread.setDaemon(true);
49 }
50 thread.setName("logback-" + threadNumber.getAndIncrement());
51 return thread;
52 }
53 };
54
55 static public ScheduledExecutorService newScheduledExecutorService() {
56 return new ScheduledThreadPoolExecutor(CoreConstants.SCHEDULED_EXECUTOR_POOL_SIZE, THREAD_FACTORY_FOR_SCHEDULED_EXECUTION_SERVICE);
57 }
58
59 /**
60 * @deprecated replaced by {@link #newThreadPoolExecutor()}
61 */
62 static public ExecutorService newExecutorService() {
63 return newThreadPoolExecutor();
64 }
65
66 /**
67 * Creates an ThreadPoolExecutor suitable for use by logback components.
68 *
69 * @since 1.4.7
70 * @return ThreadPoolExecutor
71 */
72 static public ThreadPoolExecutor newThreadPoolExecutor() {
73
74 // irrelevant parameter when LinkedBlockingQueue is in use
75 final int maximumPoolSize = CoreConstants.CORE_POOL_SIZE + 1;
76 final long keepAliveMillis = 100L;
77
78 // As of version 1.5.13, the SynchronousQueue was replaced by LinkedBlockingQueue
79 // This has the effect of queueing jobs immediately and have them run by CORE_POOL_SIZE
80 // threads. We expect jobs to arrive at a relatively slow pace compared to their duration.
81 // Note that threads are removed if idle more than keepAliveMillis
82 ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(CoreConstants.CORE_POOL_SIZE, maximumPoolSize, keepAliveMillis, TimeUnit.MILLISECONDS,
83 new LinkedBlockingQueue<>(), THREAD_FACTORY_FOR_SCHEDULED_EXECUTION_SERVICE);
84 threadPoolExecutor.allowCoreThreadTimeOut(true);
85 return threadPoolExecutor;
86
87 }
88
89 /**
90 * Shuts down an executor service.
91 * <p>
92 *
93 * @param executorService the executor service to shut down
94 */
95 static public void shutdown(ExecutorService executorService) {
96 if (executorService != null) {
97 executorService.shutdownNow();
98 }
99 }
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 }