由於項目里需要用到線程池來提高處理速度,記錄一下spring的taskExecutor執行器來實現線程池。
ThreadPoolTaskExecutor的配置在網上找了很多解釋沒找到,看了下ThreadPoolExecutor的配置,名字差不多,應該含義也差不多。只不過ThreadPoolTaskExecutor對
ThreadPoolExecutor做了包裝。
<bean id ="taskExecutor" class ="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor" >
<property name ="corePoolSize" value ="5" />
<property name ="keepAliveSeconds" value ="300" />
<property name ="maxPoolSize" value ="10" />
<property name ="queueCapacity" value ="25" />
</bean> 線程的配置文件:
corePoolSize: 線程池維護線程的最少數量
keepAliveSeconds 線程池維護線程所允許的空閑時間
maxPoolSize 線程池維護線程的最大數量
queueCapacity 線程池所使用的緩沖隊列
當一個任務通過execute(Runnable)方法欲添加到線程池時:
l 如果此時線程池中的數量小於corePoolSize,即使線程池中的線程都處於空閑狀態,也要創建新的線程來處理被添加的任務。
l 如果此時線程池中的數量等於 corePoolSize,但是緩沖隊列 workQueue未滿,那么任務被放入緩沖隊列。
l 如果此時線程池中的數量大於corePoolSize,緩沖隊列workQueue滿,並且線程池中的數量小於maximumPoolSize,建新的線程來處理被添加的任務。
l 如果此時線程池中的數量大於corePoolSize,緩沖隊列workQueue滿,並且線程池中的數量等於maximumPoolSize,那么通過 handler所指定的策略來處理此任務。也就是:處理任務的優先級為:核心線程corePoolSize、任務隊列workQueue、最大線程 maximumPoolSize,如果三者都滿了,使用handler處理被拒絕的任務。
l 當線程池中的線程數量大於 corePoolSize時,如果某線程空閑時間超過keepAliveTime,線程將被終止。這樣,線程池可以動態的調整池中的線程數。
package ch2.taskexecutor;
//執行器
import java.util.concurrent.Executor;
//異步捕獲助手
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ComponentScan;
//配置
import org.springframework.scheduling.annotation.AsyncConfigurer;
//異步支持注解
import org.springframework.scheduling.annotation.EnableAsync;
//線程池
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
//聲明這是一個配置類
@Configuration
//引入ch2.taskexecutor下面的@service,@component,@repository,@controller注冊為bean
@ComponentScan("ch2.taskexecutor")
//開啟注解:開啟異步支持
@EnableAsync
//配置類實現AsyncConfigurer接口並重寫AsyncConfigurer方法,並返回一個ThreadPoolTaskExecutor
//這樣我們就得到了一個基於線程池的TaskExecutor
public class TaskExecutorConfig implements AsyncConfigurer {
//配置類實現AsyncConfigurer接口並重寫AsyncConfigurer方法,並返回一個ThreadPoolTaskExecutor
//這樣我們就得到了一個基於線程池的TaskExecutor
@Override
public Executor getAsyncExecutor() {
// TODO Auto-generated method stub
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
//如果池中的實際線程數小於corePoolSize,無論是否其中有空閑的線程,都會給新的任務產生新的線程
taskExecutor.setCorePoolSize(5);
//連接池中保留的最大連接數。Default: 15 maxPoolSize
taskExecutor.setMaxPoolSize(10);
//queueCapacity 線程池所使用的緩沖隊列
taskExecutor.setQueueCapacity(25);
taskExecutor.initialize();
return taskExecutor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
// TODO Auto-generated method stub
return null;
}
}
package ch2.taskexecutor;
//組件聲明類
import org.springframework.stereotype.Service;
//異步聲明,如果在方法表示是異步方法,如果在類表示異步類。
//這里的方法自動被注入使用ThreadPoolTaskExecutor作為TaskExecutor(線程池)
import org.springframework.scheduling.annotation.Async;
//聲明為組件
@Service
public class AsyncService {
//異步聲明,如果在方法處表示是異步方法,如果在類處表示異步類(所有的方法都是異步方法)。
//這里的方法自動被注入使用ThreadPoolTaskExecutor作為TaskExecutor(線程池)
@Async
public void executorAsyncTask(Integer i)
{
System.out.println("執行異步:" + i);
}
//異步聲明,如果在方法處表示是異步方法,如果在類處表示異步類(所有的方法都是異步方法)。
//這里的方法自動被注入使用ThreadPoolTaskExecutor作為TaskExecutor(線程池)
@Async
public void executorAsyncTaskPlus(Integer i)
{
System.out.println("執行異步任務+1: " + (i+1));
}
}
package ch2.taskexecutor;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args)
{
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TaskExecutorConfig.class);
AsyncService asyncService = context.getBean(AsyncService.class);
for(int i = 0; i<10; i++)
{
asyncService.executorAsyncTask(i);
asyncService.executorAsyncTaskPlus(i);
}
context.close();
}
}
運行:
執行異步:0 執行異步任務+1: 1 執行異步任務+1: 3 執行異步:3 執行異步任務+1: 4 執行異步任務+1: 5 執行異步:2 執行異步:4 執行異步任務+1: 6 執行異步:5 執行異步:1 執行異步任務+1: 2 執行異步任務+1: 8 執行異步:7 執行異步任務+1: 9 執行異步任務+1: 7 執行異步任務+1: 10 執行異步:6 執行異步:9 執行異步:8
