博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring Boot使用@Async实现异步调用:自定义线程池
阅读量:5245 次
发布时间:2019-06-14

本文共 3004 字,大约阅读时间需要 10 分钟。

定义线程池

第一步,先定义一个线程池,比如:

@Configurationpublic class PoolConfig {    @Bean("testExecutor")    public Executor testExecutor() {        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();        executor.setCorePoolSize(10);        executor.setMaxPoolSize(20);        executor.setQueueCapacity(200);        executor.setKeepAliveSeconds(60);        executor.setThreadNamePrefix("testExecutor-");        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());        return executor;    }}

@EnableAsync这个注解如果在启动类已经添加过,就无需再次添加.

上面我们通过使用ThreadPoolTaskExecutor创建了一个线程池,同时设置了以下这些参数:

  • 核心线程数10:线程池创建时候初始化的线程数
  • 最大线程数20:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程
  • 缓冲队列200:用来缓冲执行任务的队列
  • 允许线程的空闲时间60秒:当超过了核心线程出之外的线程在空闲时间到达之后会被销毁
  • 线程池名的前缀:设置好了之后可以方便我们定位处理任务所在的线程池
  • 线程池对拒绝任务的处理策略:这里采用了CallerRunsPolicy策略,当线程池没有处理能力的时候,该策略会直接在 execute 方法的调用线程中运行被拒绝的任务;如果执行程序已关闭,则会丢弃该任务

使用线程池

在定义了线程池之后,我们如何让异步调用的执行任务使用这个线程池中的资源来运行呢?方法非常简单,我们只需要在@Async注解中指定线程池名即可,比如:

@Slf4j@Servicepublic class TestMethod {    public static Random random = new Random();    @Async("testExecutor")    public void one() throws Exception {        log.info("第一个");        long start = System.currentTimeMillis();        Thread.sleep(random.nextInt(10000));        long end = System.currentTimeMillis();        log.info("完成一,耗时:" + (end - start) + "毫秒");    }    @Async("testExecutor")    public void two() throws Exception {        log.info("第二个");        long start = System.currentTimeMillis();        Thread.sleep(random.nextInt(10000));        long end = System.currentTimeMillis();        log.info("完成二,耗时:" + (end - start) + "毫秒");    }    @Async("testExecutor")    public void three() throws Exception {        log.info("第三个");        long start = System.currentTimeMillis();        Thread.sleep(random.nextInt(10000));        long end = System.currentTimeMillis();        log.info("完成三,耗时:" + (end - start) + "毫秒");    }}

单元测试

最后,我们来写个单元测试来验证一下

@RunWith(SpringJUnit4ClassRunner.class)@SpringBootTestpublic class TestApplicationTests {    @Autowired    private TestMethod testMethod;    @Test    public void test() throws Exception {        testMethod.one();        testMethod.two();        testMethod.three();        Thread.currentThread().join();    }}

执行上面的单元测试,我们可以在控制台中看到所有输出的线程名前都是之前我们定义的线程池前缀名开始的,说明我们使用线程池来执行异步任务的试验成功了!

2019-05-24 09:21:24.544  INFO 10756 --- [ testExecutor-2] c.a.authorization_java.util.TestMethod   : 第二个2019-05-24 09:21:24.543  INFO 10756 --- [ testExecutor-1] c.a.authorization_java.util.TestMethod   : 第一个2019-05-24 09:21:24.544  INFO 10756 --- [ testExecutor-3] c.a.authorization_java.util.TestMethod   : 第三个2019-05-24 09:21:26.868  INFO 10756 --- [ testExecutor-3] c.a.authorization_java.util.TestMethod   : 完成三,耗时:2324毫秒2019-05-24 09:21:29.774  INFO 10756 --- [ testExecutor-2] c.a.authorization_java.util.TestMethod   : 完成二,耗时:5230毫秒2019-05-24 09:21:31.628  INFO 10756 --- [ testExecutor-1] c.a.authorization_java.util.TestMethod   : 完成一,耗时:7084毫秒

转载于:https://www.cnblogs.com/xzy-/p/10916189.html

你可能感兴趣的文章
boost 同步定时器
查看>>
[ROS] Chinese MOOC || Chapter-4.4 Action
查看>>
简单的数据库操作
查看>>
解决php -v查看到版本与phpinfo()版本不一致问题
查看>>
iOS-解决iOS8及以上设置applicationIconBadgeNumber报错的问题
查看>>
亡灵序曲-The Dawn
查看>>
Redmine
查看>>
帧的最小长度 CSMA/CD
查看>>
xib文件加载后设置frame无效问题
查看>>
编程算法 - 左旋转字符串 代码(C)
查看>>
IOS解析XML
查看>>
Python3多线程爬取meizitu的图片
查看>>
树状数组及其他特别简单的扩展
查看>>
zookeeper适用场景:分布式锁实现
查看>>
110104_LC-Display(液晶显示屏)
查看>>
httpd_Vhosts文件的配置
查看>>
php学习笔记
查看>>
普通求素数和线性筛素数
查看>>
React Router 4.0 基本使用
查看>>
PHP截取中英文混合字符
查看>>