線程池ThreadPoolTaskExecutor的使用

定義線程池

在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();
    }
}

注意

一定要記得在應用退出的時候關閉線程池

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章