Spring通過ThreadPoolTaskExecutor實現線程池技術,它是使用jdk中的Java.util.concurrent.ThreadPoolExecutor進行實現。
Spring 配置線程池,有兩種方式:
方式一:XML定義bean
<!-- 包路徑掃描 -->
<context:component-scan base-package="spring.task"/>
<!-- Spring線程池 -->
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<!-- 核心線程數 -->
<property name="corePoolSize" value="5" />
<!-- 線程池維護線程的最大數量 -->
<property name="maxPoolSize" value="10" />
<!-- 允許的空閑時間, 默認60秒 -->
<property name="keepAliveSeconds" value="60" />
<!-- 任務隊列 -->
<property name="queueCapacity" value="50" />
<!-- 線程超過空閑時間限制,均會退出直到線程數量為0 -->
<property name="allowCoreThreadTimeOut" value="true"/>
<!-- 對拒絕task的處理策略 -->
<property name="rejectedExecutionHandler">
<bean class="java.util.concurrent.ThreadPoolExecutor.DiscardOldestPolicy" />
</property>
</bean>
當一個新任務來臨時:
1)如果此時線程池中的數量小於corePoolSize,即使線程池中的線程都處於空閑狀態,也要創建新的線程來處理被添加的任務;
2)如果此時線程池中的數量等於corePoolSize,但是緩沖隊列workQueue未滿,那么任務被放入緩沖隊列;
3)如果此時線程池中的數量大於corePoolSize,緩沖隊列workQueue滿,並且線程池中的數量小於maxPoolSize,建新的線程來處理被添加的任務;
4)如果此時線程池中的數量大於corePoolSize,緩沖隊列workQueue滿,並且線程池中的數量等於maxPoolSize,那么通過handler所指定的策略來處理此任務;
5)當線程池中的線程數量大於corePoolSize時,如果某線程空閑時間超過keepAliveTime,線程將被終止,如果allowCoreThreadTimeOut為false,則線程數量維持在corePoolSize, 如果為true,則線程數量可最低降至0;
方式二:使用task:executor方式
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation= "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">
<!-- 包路徑掃描 -->
<context:component-scan base-package="spring.task"/>
<!-- 定義線程池 -->
<task:executor id="executor" pool-size="5" queue-capacity="10" rejection-policy="DISCARD_OLDEST"/>
</beans>
測試代碼
@Component
public class AsyncTask {
@Autowired
private ThreadPoolTaskExecutor executor;
@PostConstruct
public void testAsycTask() {
for (int i = 0; i < 10; i++) {
executor.execute(new Runnable() {
public void run() {
asyncTask();
}
});
}
}
private void asyncTask(){
System.out.println( "---" + Thread.currentThread().getName());
}
}
測試結果
---executor-1 ---executor-2 ---executor-3 ---executor-4 ---executor-5 ---executor-6 ---executor-7 ---executor-8 ---executor-9 ---executor-10