spring boot: 線程池ThreadPoolTaskExecutor, 多線程


由於項目里需要用到線程池來提高處理速度,記錄一下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

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM