定義線程池
在spring的配置文件中定義Bean
<!-- 配置線程池 -->
<bean id="taskExecutor"
class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<!-- 線程池維護線程的最少數量 -->
<property name="corePoolSize" value="${taskExecutor.corePoolSize}" />
<!-- 線程池維護線程所允許的空閒時間 -->
<property name="keepAliveSeconds" value="${taskExecutor.keepAliveSeconds}" />
<!-- 線程池維護線程的最大數量 -->
<property name="maxPoolSize" value="${taskExecutor.maxPoolSize}" />
<!-- 線程池所使用的緩衝隊列 -->
<property name="queueCapacity" value="${taskExecutor.queueCapacity}" />
<!-- 子線程是否允許超時,必須允許 -->
<property name="allowCoreThreadTimeOut" value="true" />
<property name="rejectedExecutionHandler">
<bean class="java.util.concurrent.ThreadPoolExecutor.DiscardOldestPolicy"/>
</property>
</bean>
system.properties
taskExecutor.corePoolSize=3
taskExecutor.maxPoolSize=3
taskExecutor.queueCapacity=50
taskExecutor.keepAliveSeconds=100
使用
taskExecutor主要有兩個方法,
- execute(Runnable task)//無返回值
- submit(Callable task) // 有返回值
/**
* 項目初始化完成 監聽器
* 啓動消費者線程
* Author: Erik Yu
* Date:2018/11/19 16:43
*/
@Component
public class ApplicationContextFinishedListener implements ApplicationListener<ContextRefreshedEvent> {
private static Logger logger = Logger.getLogger(ApplicationContextFinishedListener.class);
@Autowired
private ThreadPoolTaskExecutor taskExecutor;
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
if(event.getApplicationContext().getParent() == null){
//啓動消費者線程
logger.info("應用啓動成功,開始啓動任務消費者線程");
taskExecutor.submit(new ReportConsumer());
}
}
}
應用停止時關閉線程池
@WebListener
public class TaskExectorStopListener implements ServletContextListener {
private static Logger logger = Logger.getLogger(TaskExectorStopListener.class);
@Autowired
private ThreadPoolTaskExecutor taskExecutor;
@Override
public void contextInitialized(ServletContextEvent sce) {
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
logger.info("線程池關閉。。。。。");
taskExecutor.shutdown();
}
}
注意
一定要記得在應用退出的時候關閉線程池