1.线程池的配置创建
@Configuration
public class ThreadPoolConfig {
// 核心线程池大小
private int corePoolSize = 50;
// 最大可创建的线程数
private int maxPoolSize = 200;
// 队列最大长度
private int queueCapacity = 1000;
// 线程池维护线程所允许的空闲时间
private int keepAliveSeconds = 300;
@Bean(name = "threadPoolTaskExecutor")
public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setMaxPoolSize(maxPoolSize);
executor.setCorePoolSize(corePoolSize);
executor.setQueueCapacity(queueCapacity);
executor.setKeepAliveSeconds(keepAliveSeconds);
// 线程池对拒绝任务(无线程可用)的处理策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return executor;
}
/**
* 执行周期性或定时任务
*/
@Bean(name = "scheduledExecutorService")
protected ScheduledExecutorService scheduledExecutorService() {
return new ScheduledThreadPoolExecutor(corePoolSize,
new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build()) {
@Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
Threads.printException(r, t);
}
};
}
/**
* Security异步认证定时任务 代理线程池
*/
@Bean(name = "delegatingSecurityContextExecutorService")
protected DelegatingSecurityContextExecutorService delegatingSecurityContextExecutorService() {
return new DelegatingSecurityContextExecutorService(Executors.newFixedThreadPool(corePoolSize));
}
2.异步管理器
import com.mega.common.utils.Threads;
import com.mega.common.utils.spring.SpringUtils;
import org.springframework.security.concurrent.DelegatingSecurityContextExecutorService;
import org.springframework.stereotype.Component;
import java.util.TimerTask;
/**
* 异步任务管理器
*
* @author Jerry
*/
@Component
public class AsyncManager {
/**
* 操作延迟10毫秒
*/
private final int OPERATE_DELAY_TIME = 10;
/**
* 异步操作任务调度线程池
*/
private DelegatingSecurityContextExecutorService executor = SpringUtils.getBean("delegatingSecurityContextExecutorService");
/**
* 单例模式
*/
private AsyncManager() {
}
private static AsyncManager me = new AsyncManager();
public static AsyncManager me() {
return me;
}
/**
* 执行任务
*
* @param task 任务
*/
public void execute(TimerTask task) {
executor.execute(task);
}
/**
* 停止任务线程池
*/
public void shutdown() {
Threads.shutdownAndAwaitTermination(executor);
}
}
3.关闭线程
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.PreDestroy;
/**
* 确保应用退出时能关闭后台线程
*
* @author Jerry
*/
@Component
public class ShutdownManager {
private static final Logger logger = LoggerFactory.getLogger("sys-user");
@PreDestroy
public void destroy() {
shutdownAsyncManager();
}
/**
* 停止异步执行任务
*/
private void shutdownAsyncManager() {
try {
logger.info("====关闭后台任务任务线程池====");
AsyncManager.me().shutdown();
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
}
4. 异步工厂调用
/**
* 异步工厂(产生任务用)
*
* @author Jerry
*/
@Component
@Slf4j
public class AsyncFactory {
private static AsyncFactory asyncFactory;
@PostConstruct
public void init() {
asyncFactory = this;
}
// 异步工厂调用例子
/**
* excel上传异步保存
*
* @param header
* @param uploadCoordinationService
* @return
*/
public static TimerTask productionPlanHeaderSave(ProductionPlanHeader header, Class<?> uploadCoordinationService) {
return new TimerTask() {
@Override
public void run() {
// 进行调取的具体实现方法
Object uploadService = SpringUtils.getBean(uploadCoordinationService);
if (uploadService instanceof UploadCoordinationService) {
((UploadCoordinationService) uploadService).productionPlanHeaderSave(header);
}
}
};
}
在Service业务层面可进行使用:
AsyncManager.me().execute(AsyncFactory.productionPlanHeaderSave(header, this.getClass()));
如果项目中会使用到大量的异步线程操作,可选择集成为异步工厂来进行线程调用,安全可靠。