From 433e168326b4e72b030ce7aae547a2cc9093eaff Mon Sep 17 00:00:00 2001 From: Ceki Gulcu Date: Mon, 2 Dec 2024 19:27:09 +0100 Subject: [PATCH] ThreadPoolExecutor now uses LinkedBlockingQueue instead of SynchronousQueue. See comments in the code. Signed-off-by: Ceki Gulcu --- .../core/util/ExecutorServiceUtil.java | 29 ++--- .../core/util/ExecutorServiceUtil.java | 109 ------------------ 2 files changed, 16 insertions(+), 122 deletions(-) delete mode 100644 logback-core/src/main/java21/ch/qos/logback/core/util/ExecutorServiceUtil.java diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/ExecutorServiceUtil.java b/logback-core/src/main/java/ch/qos/logback/core/util/ExecutorServiceUtil.java index 97ac296ecd..9a7ff921d9 100755 --- a/logback-core/src/main/java/ch/qos/logback/core/util/ExecutorServiceUtil.java +++ b/logback-core/src/main/java/ch/qos/logback/core/util/ExecutorServiceUtil.java @@ -13,14 +13,7 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.SynchronousQueue; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; import ch.qos.logback.core.CoreConstants; @@ -60,8 +53,7 @@ public Thread newThread(Runnable r) { }; static public ScheduledExecutorService newScheduledExecutorService() { - return new ScheduledThreadPoolExecutor(CoreConstants.SCHEDULED_EXECUTOR_POOL_SIZE, - THREAD_FACTORY_FOR_SCHEDULED_EXECUTION_SERVICE); + return new ScheduledThreadPoolExecutor(CoreConstants.SCHEDULED_EXECUTOR_POOL_SIZE, THREAD_FACTORY_FOR_SCHEDULED_EXECUTION_SERVICE); } /** @@ -78,9 +70,20 @@ static public ExecutorService newExecutorService() { * @return ThreadPoolExecutor */ static public ThreadPoolExecutor newThreadPoolExecutor() { - return new ThreadPoolExecutor(CoreConstants.CORE_POOL_SIZE, CoreConstants.MAX_POOL_SIZE, 0L, - TimeUnit.MILLISECONDS, new SynchronousQueue(), - THREAD_FACTORY_FOR_SCHEDULED_EXECUTION_SERVICE); + + // irrelevant parameter when LinkedBlockingQueue is in use + final int maximumPoolSize = CoreConstants.CORE_POOL_SIZE + 1; + final long keepAliveMillis = 100L; + + // As of version 1.5.13, the SynchronousQueue was replaced by LinkedBlockingQueue + // This has the effect of queueing jobs immediately and have them run by CORE_POOL_SIZE + // threads. We expect jobs to arrive at a relatively slow pace compared to their duration. + // Note that threads are removed if idle more than keepAliveMillis + ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(CoreConstants.CORE_POOL_SIZE, maximumPoolSize, keepAliveMillis, TimeUnit.MILLISECONDS, + new LinkedBlockingQueue<>(), THREAD_FACTORY_FOR_SCHEDULED_EXECUTION_SERVICE); + threadPoolExecutor.allowCoreThreadTimeOut(true); + return threadPoolExecutor; + } /** diff --git a/logback-core/src/main/java21/ch/qos/logback/core/util/ExecutorServiceUtil.java b/logback-core/src/main/java21/ch/qos/logback/core/util/ExecutorServiceUtil.java deleted file mode 100644 index 221f23447d..0000000000 --- a/logback-core/src/main/java21/ch/qos/logback/core/util/ExecutorServiceUtil.java +++ /dev/null @@ -1,109 +0,0 @@ -/** - * Logback: the reliable, generic, fast and flexible logging framework. - * Copyright (C) 1999-2015, QOS.ch. All rights reserved. - * - * This program and the accompanying materials are dual-licensed under - * either the terms of the Eclipse Public License v1.0 as published by - * the Eclipse Foundation - * - * or (per the licensee's choosing) - * - * under the terms of the GNU Lesser General Public License version 2.1 - * as published by the Free Software Foundation. - */ -package ch.qos.logback.core.util; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.SynchronousQueue; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - -import ch.qos.logback.core.CoreConstants; - -/** - * Static utility methods for manipulating an {@link ExecutorService}. - * - * @author Carl Harris - * @author Mikhail Mazursky - */ -public class ExecutorServiceUtil { - private static final ThreadFactory THREAD_FACTORY_FOR_SCHEDULED_EXECUTION_SERVICE = new ThreadFactory() { - - private final AtomicInteger threadNumber = new AtomicInteger(1); - - private final ThreadFactory defaultFactory = makeThreadFactory(); - - /** - * A thread factory which may be a virtual thread factory the JDK supports it. - * - * @return - */ - private ThreadFactory makeThreadFactory() { - ThreadFactory tf = Thread.ofVirtual().factory(); - return tf; - } - - @Override - public Thread newThread(Runnable r) { - Thread thread = defaultFactory.newThread(r); - if (!thread.isDaemon()) { - thread.setDaemon(true); - } - thread.setName("logback-" + threadNumber.getAndIncrement()); - return thread; - } - }; - - static public ScheduledExecutorService newScheduledExecutorService() { - return new ScheduledThreadPoolExecutor(CoreConstants.SCHEDULED_EXECUTOR_POOL_SIZE, - THREAD_FACTORY_FOR_SCHEDULED_EXECUTION_SERVICE); - } - - /** - * @deprecated replaced by {@link #newThreadPoolExecutor()} - */ - static public ExecutorService newExecutorService() { - return newThreadPoolExecutor(); - } - - /** - * Creates an ThreadPoolExecutor suitable for use by logback components. - * - * @return ThreadPoolExecutor - * @since 1.4.7 - */ - static public ThreadPoolExecutor newThreadPoolExecutor() { - return new ThreadPoolExecutor(CoreConstants.CORE_POOL_SIZE, CoreConstants.MAX_POOL_SIZE, 0L, - TimeUnit.MILLISECONDS, new SynchronousQueue(), - THREAD_FACTORY_FOR_SCHEDULED_EXECUTION_SERVICE); - } - - /** - * Shuts down an executor service. - *

- * - * @param executorService the executor service to shut down - */ - static public void shutdown(ExecutorService executorService) { - if (executorService != null) { - executorService.shutdownNow(); - } - } - - /** - * An alternate implementation of {@linl #newThreadPoolExecutor} which returns a virtual thread per task executor - * when available. - * - * @since 1.3.12/1.4.12 - */ - static public ExecutorService newAlternateThreadPoolExecutor() { - return Executors.newVirtualThreadPerTaskExecutor(); - } -}