一、增加配置属性类

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. 删除一个数字之后数列gcd最大

    ★实验任务 顾名思义,互质序列是满足序列元素的 gcd 为 1 的序列.比如[1,2,3], [4,7,8],都是互质序列.[3,6,9]不是互质序列.现在并不要求你找出一个互质 序列,那样太简单了! ...

  2. mysql 性能分析及explain用法

    转载自http://blog.sina.com.cn/s/blog_4586764e0100o9s1.html 使用explain语句去查看分析结果 如   explain select * from ...

  3. Effective Modern C++翻译(5)-条款4:了解如何观察推导出的类型

    条款4:了解如何观察推导出的类型 那些想要知道编译器推导出的类型的人通常分为两种,第一种是实用主义者,他们的动力通常来自于软件产生的问题(例如他们还在调试解决中),他们利用编译器进行寻找,并相信这个能 ...

  4. NET Core Mvc发布带视图文件的方法!

    添加节点:<MvcRazorCompileOnPublish>false</MvcRazorCompileOnPublish>

  5. utf-8编码的中文看成2个字符,其他数字字符看成一个字符

    方法一:使用正则表达式,代码如下: function getByteLen(val) {            var len = 0;            for (var i = 0; i &l ...

  6. vSphere下安装Hyper-V

    在vSphere 5.5中默认是无法嵌套安装Hyper-V的,必须在vSphere中稍作修改. 1. 勾选这两个选项,如果是灰色,请升级虚拟机版本至最新: 2. 在配置文件中手动加入这一行参数: 3. ...

  7. 实现LinearLayout(垂直布局,Gravity内容排布)

    首先上Gravity的代码,Android原版的Gravity搞得挺复杂的,太高端了.但基本思路是使用位运算来做常量,我就自己消化了一些,按自己的思路来实现. 先上代码,在做分析. package k ...

  8. java 数据结构与算法---链表

    原理来自百度百科  一.链表的定义 链表是一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的.链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运 ...

  9. Angular中ui-select的使用

    Angular中ui-select的使用 最近工作一直很忙,没有时间整理知识,前几天项目中需要用到angular-ui-select,实现下拉框快速过滤效果,今天有时间研究了一下,终于搞明白了. 一. ...

  10. 解题:AHOI2017/HNOI2017 礼物

    题面 先不管旋转操作,只考虑增加亮度这个操作.显然这个玩意的影响是相对于$x,y$固定的,所以可以枚举增加的亮度然后O(1)算出来.为了方便我们把这个操作换种方法表示,只让一个手环改变$[-m,m]$ ...