Springboot的ThreadPoolTaskExecutor

ThreadPoolTaskExecutor是一个spring的线程池技术,被叫成什么异步线程执行器。
本质上是使用的java.util.concurrent.ThreadPoolExecutor

一、配置类`

@Configuration
public class TaskConfig {
@Bean("taskModuleExecutor")
public ThreadPoolTaskExecutor taskExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(5);
    executor.setMaxPoolSize(10);
    executor.setQueueCapacity(200);
    executor.setThreadNamePrefix("task-concurrent-work");
    executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
    executor.initialize();
    return executor;
}}

`
参数说明:

int corePoolSize:线程池维护线程的最小数量.
int maxPoolSize:线程池维护线程的最大数量. 
int maxPoolSize:线程池维护线程的最大数量. 
long keepAliveTime:空闲线程的存活时间. 
TimeUnit unit: 时间单位,现有纳秒,微秒,毫秒,秒枚举值. 
BlockingQueue<Runnable> workQueue:持有等待执行的任务队列. 
RejectedExecutionHandler handler: 用来拒绝一个任务的执行,有两种情况会发生这种情况。 

处理流程:

  当池子大小小于corePoolSize,就新建线程,并处理请求
  当池子大小等于corePoolSize,把请求放入workQueue中,池子里的空闲线程就去workQueue中取任务并处理
  当workQueue放不下任务时,就新建线程入池,并处理请求,如果池子大小撑到了maximumPoolSize,就用RejectedExecutionHandler来做拒绝处理
  当池子的线程数大于corePoolSize时,多余的线程会等待keepAliveTime长时间,如果无请求可处理就自行销毁

二、定义线程类`

@Component
public class FileCutter {

@Resource(name="taskModuleExecutor")
private TaskExecutor taskExecutor;

public void filesMng(String path, String fileName) {
    this.taskExecutor.execute(new CutFilesThread(path,fileName));
}

private class CutFilesThread implements Runnable {
    private String path;
    private String fileName;
    private CutFilesThread(String path, String fileName) {
        super();
        this.path = path;
        this.fileName = fileName;
    }
    @Override
    public void run() {
        System.out.println("barry... run...");
        //display(path, fileName);
    }
}

`

如果想要得到任务返回结果,可以将execute方法改为调用submit方法即可。
`

String resp="";
Future<String> task = threadPool.submit(new Callable<String>(){
        @Override
        public String call() throws Exception {
            String callbackResp = HttpUtils.post(Url, params, "utf-8");
            return callbackResp;
        }
    });
    try {  //注意task.get()会阻塞,直到返回数据为止,一般这样用法很少用
    	resp=task.get();
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    }`

三、在需要的地方调用
`

@Autowired
private FileCutter fileCutter;   
@RequestMapping("/cut")
@ResponseBody
public Object cut(){
    fileCutter.filesMng("your path", "your fileName");
    return "success";
}

`

四、使用springboot@Async注解
springboot中为我们提供了@Async注解,查看下源码`

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Async {
	String value() default "";
}

`
我们发现,@Async是一个类级别和方法级别的注解,当作用在方法上时,相当于这个方法重新开辟了单独的线程。

使用案例:

Controller层`
@RestController
public class controller {
	  @Autowired
	private AsyncService asyncService;
	@RequestMapping(value = "/hello",method = RequestMethod.GET)
	public String test2(){
		long start=System.currentTimeMillis();
		asyncService.NoReturn();
		return String.format("任务执行成功,耗时{%s}",System.currentTimeMillis() - start);

	}
}`
接下来在service层添加@Async`
@Service
public class AsyncService {
	@Async
	public void NoReturn(){
		try{
			Thread.sleep(3000);
			System.out.println("方法执行结束"+new Date());
		}catch (InterruptedException e){
			e.printStackTrace();
		}
	}
	}`
在启动类开启异步请求`
@EnableAsync//开启异步任务
@SpringBootApplication
public class Springboot5Application {

	public static void main(String[] args) {
		SpringApplication.run(Springboot5Application.class, args);
	}

}`
有返回值的异步
service层`
@Service
public class AsyncService {
	@Async
	public Future<String> doReturn(int i){
		try {
			Thread.sleep(500);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return new AsyncResult<>(String.format("这个是第{%s}个异步调用的证书",i));
	}
}

`

controller层`
@RestController
public class controller {
	@GetMapping("/hi")
	public Map<String,Object> testAsyncReturn()throws ExecutionException, InterruptedException {
		long start=System.currentTimeMillis();
		Map<String,Object> map=new HashMap<>();
		List<Future<String>> futures=new ArrayList<>();
		for (int i=0;i<10;i++){
			Future<String> future =asyncService.doReturn(i);
			futures.add(future);
		}
		List<String> response =new ArrayList<>();
		for (Future future : futures){
			String string =(String) future.get();
			response.add(string);
		}
		map.put("data",response);
		map.put("消耗时间",String.format("任务完成,耗时{%s}毫秒",System.currentTimeMillis()-start));
		return  map;
	}
}

`

查看结果:
{“data”:[“这个是第{0}个异步调用的证书”,“这个是第{1}个异步
调用的证书”,“这个是第{2}个异步调用的证书”,“这个是第{3}个异步调用的证书”,“这个是第{4}个异步调用的证书”,“这个是第{5}个异步调用的证书”,“这个是第{6}个异步调用的证书”,“这个是第{7}个异步调用的证书”,“这个是第{8}个异步调用的证书”,“这个是第{9}个异步调用的证书”],“消耗时间”:“任务完成,耗时{1004}毫秒”}

注意:注解扫描时,要注意过滤,避免重复实例化,因为存在覆盖问题,@Async就失效了

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值