一、使用Java代码结合@Configuration注解的配置方式

1. 新建一个配置类

import java.util.concurrent.ThreadPoolExecutor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
/*** 线程池配置**/
@Configuration
@EnableAsync
public class ThreadPoolTaskConfig {/** *   默认情况下,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,* 当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中;*  当队列满了,就继续创建线程,当线程数量大于等于maxPoolSize后,开始使用拒绝策略拒绝 *//** 核心线程数(默认线程数) */private static final int corePoolSize = 20;/** 最大线程数 */private static final int maxPoolSize = 100;/** 允许线程空闲时间(单位:默认为秒) */private static final int keepAliveTime = 10;/** 缓冲队列大小 */private static final int queueCapacity = 200;/** 线程池名前缀 */private static final String threadNamePrefix = "Async-task-";@Bean("taskExecutor") // bean的名称,默认为首字母小写的方法名public ThreadPoolTaskExecutor taskExecutor(){ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(corePoolSize);   executor.setMaxPoolSize(maxPoolSize);executor.setQueueCapacity(queueCapacity);executor.setKeepAliveSeconds(keepAliveTime);executor.setThreadNamePrefix(threadNamePrefix);// 线程池对拒绝任务的处理策略// CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());// 初始化executor.initialize();return executor;}
}

2:创建两个异步方法的类(和之前的类类似仅仅是方法上注解不一样)

如下所示:

第一个类(这里模拟取消订单后发短信,有两个发送短信的方法):

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;@Service
public class TranTest2Service {Logger log = LoggerFactory.getLogger(TranTest2Service.class);// 发送提醒短信 1@PostConstruct // 加上该注解项目启动时就执行一次该方法@Async("taskExecutor")public void sendMessage1() throws InterruptedException {log.info("发送短信方法---- 1   执行开始");Thread.sleep(5000); // 模拟耗时log.info("发送短信方法---- 1   执行结束");}// 发送提醒短信 2@PostConstruct // 加上该注解项目启动时就执行一次该方法@Async("taskExecutor")public void sendMessage2() throws InterruptedException {log.info("发送短信方法---- 2   执行开始");Thread.sleep(2000); // 模拟耗时log.info("发送短信方法---- 2   执行结束");}
}

代码中的 @Async("taskExecutor") 对应我们自定义线程池中的 @Bean("taskExecutor") ,表示使用我们自定义的线程池。

第二个类。调用发短信的方法 (异步方法不能与被调用的异步方法在同一个类中,否则无效):

@Service
public class OrderTaskServic {@Autowiredprivate TranTest2Service tranTest2Service;// 订单处理任务public void orderTask() throws InterruptedException {this.cancelOrder(); // 取消订单tranTest2Service.sendMessage1(); // 发短信的方法   1tranTest2Service.sendMessage2(); // 发短信的方法  2}// 取消订单public void cancelOrder() throws InterruptedException {System.out.println("取消订单的方法执行------开始");System.out.println("取消订单的方法执行------结束 ");}
}

注意事项:
如下方式会使@Async失效
一、异步方法使用static修饰
二、异步类没有使用@Component注解(或其他注解)导致spring无法扫描到异步类
三、异步方法不能与被调用的异步方法在同一个类中
四、类中需要使用@Autowired或@Resource等注解自动注入,不能自己手动new对象
五、如果使用SpringBoot框架必须在启动类中增加@EnableAsync注解

SpringBoot2线程池的创建以及执行异步任务相关推荐

  1. JUC多线程:线程池的创建及工作原理 和 Executor 框架

    一.什么是线程池: 线程池主要是为了解决 新任务执行时,应用程序为任务创建一个新线程 以及 任务执行完毕时,销毁线程所带来的开销.通过线程池,可以在项目初始化时就创建一个线程集合,然后在需要执行新任务 ...

  2. 谈谈java的线程池(创建、机制)

    目录 Executors创建线程池默认方法 自定义线程池 Executors创建线程池默认方法 newFixedThreadPool()方法,该方法返回一个固定数量的线程池,该方法的线程数始终不变,当 ...

  3. java(线程池的创建方式,和线程池的原理)

    1.为什么要使用线程池:   减少资源消耗,通过重复的使用已创建好的线程,避免了线程的频繁创建和销毁所造成的消耗 提高响应速度,当任务到达的时候,不需要再去创建,可以直接使用已经创建好的线程就能立即执 ...

  4. Java同步—线程池的创建和使用

    线程池 构建一个新的线程是有一定代价的,因为涉及到与操作系统的交互.如果程序中需要使用大量生命周期很短的线程,就应该使用线程池. 将Runnable对象交给线程池来执行,就会有一个线程调用run方法, ...

  5. 线程池的参数及执行顺序

    线程池的优点 降低系统资源消耗,通过复用已存在的线程,降低线程创建和销毁造成的开销: 提高系统响应速度,当有任务到达时,通过复用已存在的线程,无需等待新线程创建便立即能够执行. 方便线程并发数的管控, ...

  6. Android 应用开发 之通过AsyncTask与ThreadPool(线程池)两种方式异步加载大量数据的分析与对比

    Android 应用开发 之通过AsyncTask与ThreadPool(线程池)两种方式异步加载大量数据的分析与对比 标签: AndroidAsyncTaskThreadPool异步加载view 2 ...

  7. 线程池的创建及参数设置详解

    一. 常见线程池 线程池的创建方法主要有两类,第一是通过Executors 创建线程池,第二是通过 ThreadPoolExecutor 创建线程池. 首先我们来看通过Executors 创建的线程池 ...

  8. JAVA线程池ThreadPoolExecutor创建以及各参数的详细说明

    最近把线程很多的东西都温故了一遍,发现还漏了个线程池,今天看了些线程池的文章,然后加入了自己的理解,总结如下 首先看下一个线程池的最简单的构造方法如下 * @param corePoolSize th ...

  9. Linux下通用线程池的创建与使用

    Linux下通用线程池的创建与使用 本文给出了一个通用的线程池框架,该框架将与线程执行相关的任务进行了高层次的抽象,使之与具体的执行任务无关.另外该线程池具有动态伸缩性,它能根据执行任务的轻重自动调整 ...

  10. JAVA线程池ScheduledExecutorService周期性地执行任务 与单个Thread周期性执行任务的异常处理

    JAVA线程池ScheduledExecutorService周期性地执行任务 与单个Thread周期性执行任务的异常处理 参考文章: (1)JAVA线程池ScheduledExecutorServi ...

最新文章

  1. 谷歌colab实验室使用GPU
  2. c++ 11 锁_国民技术面向智能锁市场提供全系芯片与开源安全解决方案
  3. linux系统负载检查方法
  4. SQL Server事务
  5. 2012.1.15---学习笔记
  6. 4.RabbitMQ Linux安装
  7. [vue] 说说你对slot的理解有多少?slot使用场景有哪些?
  8. 外贸网站需要ERP系统吗?
  9. Server的Transfer和Response的Redirect
  10. CSS——简写属性(在padding和margin这样的简写属性中,值赋值的顺序是top、right、bottom、left)...
  11. Google两步验证的工作原理
  12. python图像颜色反转_OpenCV图像颜色反转算法详解
  13. VBA word 文件类型html,Word VBA SaveAs错误:不兼容的文件类型和文件扩展名
  14. 用户画像项目两大核心内容之一“one_id”(含SQL实现代码)
  15. C语言main函数参数[转:C语言中文网]
  16. flac - 安装使用
  17. 使用WordPress插件搭建一个商城(一)(小白推荐)
  18. 初雨CPPHelper使用说明
  19. leaflet调用2019天地图接口
  20. 在ubuntu16.04 64-bit上安装佳能打印机驱动Linux_UFRII_PrinterDriver_V320_us_EN

热门文章

  1. 中兴echat_中兴高达震撼发布12款新品 助力专网行业融合发展
  2. Dijkstra算法 简易理解(原创)
  3. Sequence of methods in form and table in AX
  4. Amazon AWS S3 上传文件 并获取公用url
  5. uva11992-Fast Matrix Operations(区间增值、改值)
  6. 数据结构与算法分析:第1、2章:引论和算法分析
  7. SVN—如何安装SVN客户端软件
  8. WdatePicker—WdatePicker日历控件使用方法
  9. Vue数据更新视图不更新的几种解决方案
  10. 记录一枚验证URL的js正则表达式