因为项目中 @PostConstruct 初始化方法中的逻辑比较久, 阻塞了主线程, 耽误启动时间,就想者优化一下, 周末查了一下解决了。
上代码:
禁止在项目中 new Thread();
1: 配置项目线程池:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
/**
* 线程池配置
*/
@Configuration
public class ThreadExecutorConfig {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
/** 核心线程数 */
private int corePoolSize = 10;
/** 最大线程数 */
private int maxPoolSize = 200;
/** 队列数 */
private int queueCapacity = 10;
@Bean("testAsync")
public ExecutorService testFxbDrawExecutor(){
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(queueCapacity);
executor.setThreadNamePrefix("testAsync");
// rejection-policy:当pool已经达到max size的时候,如何处理新任务
// CALLER_RUNS:不在新线程中执行任务,而是由调用者所在的线程来执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 执行初始化
executor.initialize();
return executor.getThreadPoolExecutor();
}
}
2: 异步方法:
/**
* @author tangjiandong
* @version 1.0
* @description:
* @date 2021年11月21日 20:22
*/
public interface TestService {
void test();
}
import com.xxxx.service.TestService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
/**
* @author tangjiandong
* @version 1.0
* @description:
* @date 2021年11月21日 20:07
*/
@Service
@Slf4j
@Lazy(false)
public class TestServiceImpl implements TestService {
@Async("testAsync") //指定线程池
@Override
public void test() {
System.out.println("------------------------异步方法开始 " + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("----------------异步方法执行完了" + Thread.currentThread().getName());
}
}
3: @ PostConstruct 调用异步方法, 注意, PostConstruct 不能在同一个类中调@async
import com.xxxx.service.TestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
/**
* @author tangjiandong
* @version 1.0
* @description:
* @date 2021年11月21日 20:17
*/
@Service
public class LooooServiceImpl {
@Autowired
private TestService testService;
@PostConstruct
public void test(){
System.out.println("-1111111111111111111111111111111111");
testService.test();
System.out.println("-2222222222222222222222222222222222");
}
}
4: 启动类加上 启用异步
5: 执行结果:
错误请忽略。。。。