mirror of
https://github.com/continew-org/continew-starter.git
synced 2025-09-17 10:58:38 +08:00
refactor: 应用关闭,关闭自定义线程池ScheduledExecutorService
* 程序结束,关闭ScheduledExecutorService 线程池。
This commit is contained in:
@@ -20,6 +20,7 @@ import cn.hutool.core.thread.ThreadUtil;
|
|||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
@@ -30,9 +31,13 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
|||||||
import top.continew.starter.core.constant.PropertiesConstants;
|
import top.continew.starter.core.constant.PropertiesConstants;
|
||||||
import top.continew.starter.core.util.ExceptionUtils;
|
import top.continew.starter.core.util.ExceptionUtils;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.RunnableFuture;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 线程池自动配置
|
* 线程池自动配置
|
||||||
@@ -69,6 +74,11 @@ public class ThreadPoolAutoConfiguration {
|
|||||||
executor.setKeepAliveSeconds(properties.getKeepAliveSeconds());
|
executor.setKeepAliveSeconds(properties.getKeepAliveSeconds());
|
||||||
// 配置当池内线程数已达到上限的时候,该如何处理新任务:不在新线程中执行任务,而是由调用者所在的线程来执行
|
// 配置当池内线程数已达到上限的时候,该如何处理新任务:不在新线程中执行任务,而是由调用者所在的线程来执行
|
||||||
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
|
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
|
||||||
|
// 关闭线程池是否等待任务完成
|
||||||
|
executor.setWaitForTasksToCompleteOnShutdown(properties.isWaitForTasksToCompleteOnShutdown());
|
||||||
|
// 执行器在关闭时阻塞的最长毫秒数,以等待剩余任务完成执行。
|
||||||
|
executor.setAwaitTerminationMillis(properties.getAwaitTerminationMillis());
|
||||||
|
|
||||||
log.debug("[ContiNew Starter] - Auto Configuration 'ThreadPoolTaskExecutor' completed initialization.");
|
log.debug("[ContiNew Starter] - Auto Configuration 'ThreadPoolTaskExecutor' completed initialization.");
|
||||||
return executor;
|
return executor;
|
||||||
}
|
}
|
||||||
@@ -88,7 +98,65 @@ public class ThreadPoolAutoConfiguration {
|
|||||||
ExceptionUtils.printException(runnable, throwable);
|
ExceptionUtils.printException(runnable, throwable);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// 应用关闭时,关闭线程池
|
||||||
|
SpringApplication.getShutdownHandlers().add(() -> {
|
||||||
|
shutdown(executor, properties);
|
||||||
|
});
|
||||||
log.debug("[ContiNew Starter] - Auto Configuration 'ScheduledExecutorService' completed initialization.");
|
log.debug("[ContiNew Starter] - Auto Configuration 'ScheduledExecutorService' completed initialization.");
|
||||||
return executor;
|
return executor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据相应的配置设置关闭 ExecutorService
|
||||||
|
*
|
||||||
|
* @see org.springframework.scheduling.concurrent.ExecutorConfigurationSupport#shutdown()
|
||||||
|
*/
|
||||||
|
public void shutdown(ExecutorService executor, ThreadPoolProperties properties) {
|
||||||
|
log.debug("[ContiNew Starter] - Shutting down ScheduledExecutorService start.");
|
||||||
|
if (executor != null) {
|
||||||
|
if (properties.isWaitForTasksToCompleteOnShutdown()) {
|
||||||
|
executor.shutdown();
|
||||||
|
} else {
|
||||||
|
for (Runnable remainingTask : executor.shutdownNow()) {
|
||||||
|
cancelRemainingTask(remainingTask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
awaitTerminationIfNecessary(executor, properties);
|
||||||
|
log.debug("[ContiNew Starter] - Shutting down ScheduledExecutorService complete.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel the given remaining task which never commenced execution,
|
||||||
|
* as returned from {@link ExecutorService#shutdownNow()}.
|
||||||
|
*
|
||||||
|
* @param task the task to cancel (typically a {@link RunnableFuture})
|
||||||
|
* @see RunnableFuture#cancel(boolean)
|
||||||
|
* @since 5.0.5
|
||||||
|
*/
|
||||||
|
protected void cancelRemainingTask(Runnable task) {
|
||||||
|
if (task instanceof Future<?> future) {
|
||||||
|
future.cancel(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wait for the executor to terminate, according to the value of the properties
|
||||||
|
*/
|
||||||
|
private void awaitTerminationIfNecessary(ExecutorService executor, ThreadPoolProperties properties) {
|
||||||
|
if (properties.getAwaitTerminationMillis() > 0) {
|
||||||
|
try {
|
||||||
|
if (!executor.awaitTermination(properties.getAwaitTerminationMillis(), TimeUnit.MILLISECONDS)) {
|
||||||
|
if (log.isWarnEnabled()) {
|
||||||
|
log.warn("[ContiNew Starter] - Timed out while waiting for executor 'ScheduledExecutorService' to terminate.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
if (log.isWarnEnabled()) {
|
||||||
|
log.warn("[ContiNew Starter] - Interrupted while waiting for executor 'ScheduledExecutorService' to terminate");
|
||||||
|
}
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -54,6 +54,16 @@ public class ThreadPoolProperties {
|
|||||||
*/
|
*/
|
||||||
private int keepAliveSeconds = 300;
|
private int keepAliveSeconds = 300;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭线程池是否等待任务完成
|
||||||
|
*/
|
||||||
|
private boolean waitForTasksToCompleteOnShutdown = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行器在关闭时阻塞的最长毫秒数,以等待剩余任务完成执行。
|
||||||
|
*/
|
||||||
|
private long awaitTerminationMillis = 0;
|
||||||
|
|
||||||
public boolean isEnabled() {
|
public boolean isEnabled() {
|
||||||
return enabled;
|
return enabled;
|
||||||
}
|
}
|
||||||
@@ -93,4 +103,20 @@ public class ThreadPoolProperties {
|
|||||||
public void setKeepAliveSeconds(int keepAliveSeconds) {
|
public void setKeepAliveSeconds(int keepAliveSeconds) {
|
||||||
this.keepAliveSeconds = keepAliveSeconds;
|
this.keepAliveSeconds = keepAliveSeconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isWaitForTasksToCompleteOnShutdown() {
|
||||||
|
return waitForTasksToCompleteOnShutdown;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWaitForTasksToCompleteOnShutdown(boolean waitForTasksToCompleteOnShutdown) {
|
||||||
|
this.waitForTasksToCompleteOnShutdown = waitForTasksToCompleteOnShutdown;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getAwaitTerminationMillis() {
|
||||||
|
return awaitTerminationMillis;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAwaitTerminationMillis(long awaitTerminationMillis) {
|
||||||
|
this.awaitTerminationMillis = awaitTerminationMillis;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user