一、增加配置属性类

package com.chhliu.springboot.async.configuration;
import org.springframework.boot.context.properties.ConfigurationProperties;
  
@ConfigurationProperties(prefix = "spring.task.pool") // 该注解的locations已经被启用,现在只要是在环境中,都会优先加载
public class TaskThreadPoolConfig {
 private int corePoolSize;
  
 private int maxPoolSize;
  
 private int keepAliveSeconds;
  
 private int queueCapacity;
   
 …………省略getter,setter方法…………
}

二、创建线程池

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.chhliu.springboot.async.pool;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
  
import com.chhliu.springboot.async.configuration.TaskThreadPoolConfig;
  
@Configuration
@EnableAsync
public class TaskExecutePool {
  
 @Autowired
 private TaskThreadPoolConfig config;
  
 @Bean
 public Executor myTaskAsyncPool() {
  ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
  executor.setCorePoolSize(config.getCorePoolSize());
  executor.setMaxPoolSize(config.getMaxPoolSize());
  executor.setQueueCapacity(config.getQueueCapacity());
  executor.setKeepAliveSeconds(config.getKeepAliveSeconds());
  executor.setThreadNamePrefix("MyExecutor-");
  
  // rejection-policy:当pool已经达到max size的时候,如何处理新任务
  // CALLER_RUNS:不在新线程中执行任务,而是由调用者所在的线程来执行
  executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
  executor.initialize();
  return executor;
 }
}

  

 
 

三、在主类中开启配置支持

package com.chhliu.springboot.async;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.scheduling.annotation.EnableAsync;
  
import com.chhliu.springboot.async.configuration.TaskThreadPoolConfig;
  
@SpringBootApplication
@EnableAsync
@EnableConfigurationProperties({TaskThreadPoolConfig.class} ) // 开启配置属性支持
public class SpringbootAsyncApplication {
  
 public static void main(String[] args) {
  SpringApplication.run(SpringbootAsyncApplication.class, args);
 }
}

  

 
 
 

四、测试类

package com.chhliu.springboot.async.pool;
  
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
  
@Component
public class AsyncTask {
 protected final Logger logger = LoggerFactory.getLogger(this.getClass());
   
 @Async("myTaskAsyncPool") //myTaskAsynPool即配置线程池的方法名,此处如果不写自定义线程池的方法名,会使用默认的线程池
 public void doTask1(int i) throws InterruptedException{
  logger.info("Task"+i+" started.");
 }
}

  

 
 
 

五、测试

package com.chhliu.springboot.async;
import java.util.concurrent.ExecutionException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
  
import com.chhliu.springboot.async.pool.AsyncTask;
  
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootAsyncApplicationTests {
 protected final Logger logger = LoggerFactory.getLogger(this.getClass());
 @Autowired
 private AsyncTask asyncTask;
  
 @Test
 public void AsyncTaskTest() throws InterruptedException, ExecutionException {
  
  for (int i = 0; i < 100; i++) {
   asyncTask.doTask1(i);
  }
  
  logger.info("All tasks finished.");
 }
}

  

 
 

测试结果如下:

2017-03-20 20:15:15.208 INFO 4068 --- [ MyExecutor-10] c.c.springboot.async.pool.AsyncTask  : Task60 started.
2017-03-20 20:15:15.208 INFO 4068 --- [ MyExecutor-25] c.c.springboot.async.pool.AsyncTask  : Task61 started.
2017-03-20 20:15:15.208 INFO 4068 --- [ MyExecutor-6] c.c.springboot.async.pool.AsyncTask  : Task62 started.
2017-03-20 20:15:15.208 INFO 4068 --- [ MyExecutor-23] c.c.springboot.async.pool.AsyncTask  : Task63 started.
2017-03-20 20:15:15.208 INFO 4068 --- [ MyExecutor-20] c.c.springboot.async.pool.AsyncTask  : Task64 started.
2017-03-20 20:15:15.208 INFO 4068 --- [ MyExecutor-19] c.c.springboot.async.pool.AsyncTask  : Task65 started.
2017-03-20 20:15:15.208 INFO 4068 --- [ MyExecutor-16] c.c.springboot.async.pool.AsyncTask  : Task66 started.
2017-03-20 20:15:15.208 INFO 4068 --- [ MyExecutor-15] c.c.springboot.async.pool.AsyncTask  : Task67 started.
2017-03-20 20:15:15.208 INFO 4068 --- [ MyExecutor-12] c.c.springboot.async.pool.AsyncTask  : Task68 started.
2017-03-20 20:15:15.209 INFO 4068 --- [ MyExecutor-1] c.c.springboot.async.pool.AsyncTask  : Task69 started.
2017-03-20 20:15:15.209 INFO 4068 --- [ MyExecutor-11] c.c.springboot.async.pool.AsyncTask  : Task81 started.
2017-03-20 20:15:15.209 INFO 4068 --- [ MyExecutor-8] c.c.springboot.async.pool.AsyncTask  : Task82 started.
2017-03-20 20:15:15.209 INFO 4068 --- [ MyExecutor-7] c.c.springboot.async.pool.AsyncTask  : Task83 started.
2017-03-20 20:15:15.209 INFO 4068 --- [ MyExecutor-4] c.c.springboot.async.pool.AsyncTask  : Task84 started.
2017-03-20 20:15:15.209 INFO 4068 --- [ MyExecutor-29] c.c.springboot.async.pool.AsyncTask  : Task85 started.
2017-03-20 20:15:15.209 INFO 4068 --- [ MyExecutor-21] c.c.springboot.async.pool.AsyncTask  : Task86 started.
2017-03-20 20:15:15.209 INFO 4068 --- [ MyExecutor-17] c.c.springboot.async.pool.AsyncTask  : Task88 started.

  

   

测试结果ok!

 

六、配置默认的线程池

如果我们想使用默认的线程池,但是只是想修改默认线程池的配置,那怎么做了,此时我们需要实现AsyncConfigurer类,示例代码如下:

import java.lang.reflect.Method;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import com.chhliu.cq.emailservice.threadconfiguration.TaskThreadPoolConfig;
import lombok.extern.slf4j.Slf4j;
  
/**
 * 注意:该线程池被所有的异步任务共享,而不属于某一个异步任务
 * 描述:配置异步任务的线程池
 * @author chhliu
 * 创建时间:2017年5月22日 上午10:20:56
 * @version 1.2.0
 */
@Slf4j
@Configuration
public class AsyncTaskExecutePool implements AsyncConfigurer{
  
 @Autowired
 private TaskThreadPoolConfig config; // 配置属性类,见上面的代码
  
 @Override
 public Executor getAsyncExecutor() {
  ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
  executor.setCorePoolSize(config.getCorePoolSize());
  executor.setMaxPoolSize(config.getMaxPoolSize());
  executor.setQueueCapacity(config.getQueueCapacity());
  executor.setKeepAliveSeconds(config.getKeepAliveSeconds());
  executor.setThreadNamePrefix("taskExecutor-");
  
  // rejection-policy:当pool已经达到max size的时候,如何处理新任务
  // CALLER_RUNS:不在新线程中执行任务,而是由调用者所在的线程来执行
  executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
  executor.initialize();
  return executor;
 }
  
 @Override
 public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {// 异步任务中异常处理
  return new AsyncUncaughtExceptionHandler() {
     
   @Override
   public void handleUncaughtException(Throwable arg0, Method arg1, Object... arg2) {
    log.error("=========================="+arg0.getMessage()+"=======================", arg0);
    log.error("exception method:"+arg1.getName());
   }
  };
 }
}

  

   

spring boot使用自定义配置的线程池执行Async异步任务的更多相关文章

  1. spring boot yaml 自定义配置 映射到 java POJO

    只需要一个注解就ok: @ConfigurationProperties("user.other") “user.other” 这个值匹配的是user下的other对象 yaml ...

  2. 【Spring Boot】Spring Boot之自定义配置参数绑定到Java Bean

    一.@Value方式 1.我的配置文件:application-dev.yml # 自定义项目配置 startproject: pro1: pro2: pro3: pro4: lists: - ' - ...

  3. Spring使用ThreadPoolTaskExecutor自定义线程池及实现异步调用

    多线程一直是工作或面试过程中的高频知识点,今天给大家分享一下使用 ThreadPoolTaskExecutor 来自定义线程池和实现异步调用多线程. 一.ThreadPoolTaskExecutor ...

  4. Spring Boot2 系列教程(十八)Spring Boot 中自定义 SpringMVC 配置

    用过 Spring Boot 的小伙伴都知道,我们只需要在项目中引入 spring-boot-starter-web 依赖,SpringMVC 的一整套东西就会自动给我们配置好,但是,真实的项目环境比 ...

  5. 自定义spring boot的自动配置

    文章目录 添加Maven依赖 创建自定义 Auto-Configuration 添加Class Conditions 添加 bean Conditions Property Conditions Re ...

  6. 【转】spring boot application.properties 配置参数详情

    multipart multipart.enabled 开启上传支持(默认:true) multipart.file-size-threshold: 大于该值的文件会被写到磁盘上 multipart. ...

  7. 小代学Spring Boot之自定义Starter

    想要获取更多文章可以访问我的博客 - 代码无止境. 上一篇小代同学在Spring Boot项目中配置了数据源,但是通常来讲我们访问数据库都会通过一个ORM框架,很少会直接使用JDBC来执行数据库操作的 ...

  8. Tomcat启动时加载数据到缓存---web.xml中listener加载顺序(例如顺序:1、初始化spring容器,2、初始化线程池,3、加载业务代码,将数据库中数据加载到内存中)

    最近公司要做功能迁移,原来的后台使用的Netty,现在要迁移到在uap上,也就是说所有后台的代码不能通过netty写的加载顺序加载了. 问题就来了,怎样让迁移到tomcat的代码按照原来的加载顺序进行 ...

  9. 初识Spring Boot框架(二)之DIY一个Spring Boot的自动配置

    在上篇博客初识Spring Boot框架中我们初步见识了SpringBoot的方便之处,很多小伙伴可能也会好奇这个Spring Boot是怎么实现自动配置的,那么今天我就带小伙伴我们自己来实现一个简单 ...

随机推荐

  1. Java网络编程二:Socket详解

    Socket又称套接字,是连接运行在网络上两个程序间的双向通讯的端点. 一.使用Socket进行网络通信的过程 服务端:服务器程序将一个套接字绑定到一个特定的端口,并通过此套接字等待和监听客户端的连接 ...

  2. 微信小程序 功能函数 客服

    <view> <view class='btn-img'> <image class='image-full' src='../../imgs/index/tab6.pn ...

  3. Java容器深入浅出之Map、HashMap、Hashtable及其它实现类

    在Java中,Set的底层事实上是基于Map实现的,Map内部封装了一个Entry内部接口,由实现类来封装key-value对,当value值均为null时,key的集合就形成了Set.因此,Map集 ...

  4. python自动化之web抓取

    ''' 从web抓取数据: webbrowser:是python自带的,打开浏览器获取指定页面. requests:从因特网上下载文件和网页. Beautiful Soup:解析HTML,即网页编写的 ...

  5. JS中JSON对象和JSON字符串的相互转化

    转:http://www.cnblogs.com/wbyp/p/7086318.html 一.JSON字符串转换为JSON对象 var str = '{"name":"c ...

  6. P4291 [HAOI2008]排名系统

    题目描述 排名系统通常要应付三种请求:上传一条新的得分记录.查询某个玩家的当前排名以及返回某个区段内的排名记录.当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除.为了减轻服务器负担,在返回 ...

  7. P2303 [SDOi2012]Longge的问题

    题目描述 Longge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题.现在问题来了:给定一个整数N,你需要求出∑gcd(i, N)(1<=i <=N). 输入输出格式 输入格式: 一 ...

  8. uoj35 后缀排序

    题目链接:http://uoj.ac/problem/35 这是一道模板题. 读入一个长度为 n 的由小写英文字母组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第 ...

  9. Missing $ inserted解决方法

    目录 问题描述 解决 参考 问题描述 在学习LaTex Tutorial的时候,按照教程输入矩阵的时候发现出现了 ! Missing $ inserted的错误. 解决 在矩阵前后要加上$,如图所示 ...

  10. 【bzoj3926】 Zjoi2015—诸神眷顾的幻想乡

    http://www.lydsy.com/JudgeOnline/problem.php?id=3926 (题目链接) 题意 给出一棵树,每个节点有一个编号,范围在${[0,9]}$.一个序列是指树上 ...