mirror of
https://github.com/continew-org/continew-starter.git
synced 2025-09-09 20:57:23 +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 org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
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.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.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 线程池自动配置
|
||||
@@ -69,6 +74,11 @@ public class ThreadPoolAutoConfiguration {
|
||||
executor.setKeepAliveSeconds(properties.getKeepAliveSeconds());
|
||||
// 配置当池内线程数已达到上限的时候,该如何处理新任务:不在新线程中执行任务,而是由调用者所在的线程来执行
|
||||
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
|
||||
// 关闭线程池是否等待任务完成
|
||||
executor.setWaitForTasksToCompleteOnShutdown(properties.isWaitForTasksToCompleteOnShutdown());
|
||||
// 执行器在关闭时阻塞的最长毫秒数,以等待剩余任务完成执行。
|
||||
executor.setAwaitTerminationMillis(properties.getAwaitTerminationMillis());
|
||||
|
||||
log.debug("[ContiNew Starter] - Auto Configuration 'ThreadPoolTaskExecutor' completed initialization.");
|
||||
return executor;
|
||||
}
|
||||
@@ -88,7 +98,65 @@ public class ThreadPoolAutoConfiguration {
|
||||
ExceptionUtils.printException(runnable, throwable);
|
||||
}
|
||||
};
|
||||
// 应用关闭时,关闭线程池
|
||||
SpringApplication.getShutdownHandlers().add(() -> {
|
||||
shutdown(executor, properties);
|
||||
});
|
||||
log.debug("[ContiNew Starter] - Auto Configuration 'ScheduledExecutorService' completed initialization.");
|
||||
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 boolean waitForTasksToCompleteOnShutdown = false;
|
||||
|
||||
/**
|
||||
* 执行器在关闭时阻塞的最长毫秒数,以等待剩余任务完成执行。
|
||||
*/
|
||||
private long awaitTerminationMillis = 0;
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
@@ -93,4 +103,20 @@ public class ThreadPoolProperties {
|
||||
public void setKeepAliveSeconds(int 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