1、配置线程配置类

 package test;

 import java.util.concurrent.Executor;

 import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; @Configuration
@ComponentScan("test")
@EnableAsync
// 线程配置类
public class AsyncTaskConfig implements AsyncConfigurer { // ThredPoolTaskExcutor的处理流程
// 当池子大小小于corePoolSize,就新建线程,并处理请求
// 当池子大小等于corePoolSize,把请求放入workQueue中,池子里的空闲线程就去workQueue中取任务并处理
// 当workQueue放不下任务时,就新建线程入池,并处理请求,如果池子大小撑到了maximumPoolSize,就用RejectedExecutionHandler来做拒绝处理
// 当池子的线程数大于corePoolSize时,多余的线程会等待keepAliveTime长时间,如果无请求可处理就自行销毁 @Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(5);// 最小线程数
taskExecutor.setMaxPoolSize(10);// 最大线程数
taskExecutor.setQueueCapacity(25);// 等待队列 taskExecutor.initialize(); return taskExecutor;
} @Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return null;
}
}

2、定义线程执行任务类

 package test;

 import java.util.Random;
import java.util.concurrent.Future; import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service; @Service
// 线程执行任务类
public class AsyncTaskService { Random random = new Random();// 默认构造方法 @Async
// 表明是异步方法
// 无返回值
public void executeAsyncTask(Integer i) {
System.out.println("执行异步任务:" + i);
} /**
* 异常调用返回Future
*
* @param i
* @return
* @throws InterruptedException
*/
@Async
public Future<String> asyncInvokeReturnFuture(int i) throws InterruptedException {
System.out.println("input is " + i);
Thread.sleep(1000 * random.nextInt(i)); Future<String> future = new AsyncResult<String>("success:" + i);// Future接收返回值,这里是String类型,可以指明其他类型 return future;
}
}

3、调用

 package test;

 import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future; import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.core.task.TaskRejectedException; public class Application { public static void main(String[] args) throws InterruptedException, ExecutionException {
// testVoid(); testReturn();
} // 测试无返回结果
private static void testVoid() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AsyncTaskConfig.class);
AsyncTaskService asyncTaskService = context.getBean(AsyncTaskService.class); // 创建了20个线程
for (int i = 1; i <= 20; i++) {
asyncTaskService.executeAsyncTask(i);
} context.close();
} // 测试有返回结果
private static void testReturn() throws InterruptedException, ExecutionException {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AsyncTaskConfig.class);
AsyncTaskService asyncTaskService = context.getBean(AsyncTaskService.class); List<Future<String>> lstFuture = new ArrayList<Future<String>>();// 存放所有的线程,用于获取结果 // 创建100个线程
for (int i = 1; i <= 100; i++) {
while (true) {
try {
// 线程池超过最大线程数时,会抛出TaskRejectedException,则等待1s,直到不抛出异常为止
Future<String> future = asyncTaskService.asyncInvokeReturnFuture(i);
lstFuture.add(future); break;
} catch (TaskRejectedException e) {
System.out.println("线程池满,等待1S。");
Thread.sleep(1000);
}
}
} // 获取值。get是阻塞式,等待当前线程完成才返回值
for (Future<String> future : lstFuture) {
System.out.println(future.get());
} context.close();
}
}

maven配置

 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>TestAysc</groupId>
<artifactId>TestAysc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>1.5.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
</dependencies>
</project>

结果展示:

1、无返回结果

2、有返回结果

Spring boot多线程的更多相关文章

  1. 【转】Spring Boot 构建应用——快速构建 Spring Boot 应用

    Spring Boot 简化了 Spring 应用开发,不需要配置就能运行 Spring 应用,Spring Boot 的自动配置是通过 Spring 4.x 的条件注解 @Conditional 来 ...

  2. Spring Boot 定时任务单线程和多线程

    Spring Boot 的定时任务: 第一种:把参数配置到.properties文件中: 代码: package com.accord.task; import java.text.SimpleDat ...

  3. spring boot 2X中@Scheduled实现定时任务及多线程配置

    使用@Scheduled 可以很容易实现定时任务 spring boot的版本 2.1.6.RELEASE package com.abc.demo.common; import org.slf4j. ...

  4. Spring Boot 定时+多线程执行

    Spring Boot 定时任务有多种实现方式,我在一个微型项目中通过注解方式执行定时任务. 具体执行的任务,通过多线程方式执行,单线程执行需要1小时的任务,多线程下5分钟就完成了. 执行效率提升10 ...

  5. spring boot 并发请求,其他系统接口,丢失request的header信息【多线程、线程池、@Async 】

    场景:一次迭代在灰度环境发版时,测试反馈说我开发的那个功能,查询接口有部分字段数据是空的,后续排查日志,发现日志如下: feign.RetryableException: cannot retry d ...

  6. (转)spring boot注解 --@EnableAsync 异步调用

    原文:http://www.cnblogs.com/azhqiang/p/5609615.html EnableAsync注解的意思是可以异步执行,就是开启多线程的意思.可以标注在方法.类上. @Co ...

  7. spring boot注解 --@EnableAsync 异步调用

    EnableAsync注解的意思是可以异步执行,就是开启多线程的意思.可以标注在方法.类上. @Component public class Task { @Async public void doT ...

  8. spring boot / cloud (十九) 并发消费消息,如何保证入库的数据是最新的?

    spring boot / cloud (十九) 并发消费消息,如何保证入库的数据是最新的? 消息中间件在解决异步处理,模块间解耦和,和高流量场景的削峰,等情况下有着很广泛的应用 . 本文将跟大家一起 ...

  9. 如何通过Spring Boot配置动态数据源访问多个数据库

    之前写过一篇博客<Spring+Mybatis+Mysql搭建分布式数据库访问框架>描述如何通过Spring+Mybatis配置动态数据源访问多个数据库.但是之前的方案有一些限制(原博客中 ...

随机推荐

  1. .net core 简单项目的创建

    1.linux 安装net coref https://www.microsoft.com/net/learn/get-started/linuxubuntu 2.创建目录 2.创建控制台项目 第一次 ...

  2. Feature Extractor[googlenet v1]

    1 - V1 google团队在模型上,更多考虑的是实用性,也就是如何能让强大的深度学习模型能够用在嵌入式或者移动设备上.传统的想增强模型的方法无非就是深度和宽度,而如果简单的增加深度和宽度,那么带来 ...

  3. Kafka Topic Api

    Pom: <dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka_2.10 ...

  4. Volley使用

    Volley是常用的网络请求框架,主要的用法如下: 获取字符串: public static void volleyTest1(final Context context){ RequestQueue ...

  5. 在Linux的Windows子系统上(WSL)使用Docker(Ubuntu)

    背景 平时开发大部人都是在提供了高效GUI的window下工作,但是真正部署环境普遍都是在Linux中,所以为了让开发环境和部署环境统一,我们需要在windows模拟LInux环境,以前我们可能通过虚 ...

  6. 《React Native 精解与实战》书籍连载「React Native 网络请求与列表绑定」

    此文是我的出版书籍<React Native 精解与实战>连载分享,此书由机械工业出版社出版,书中详解了 React Native 框架底层原理.React Native 组件布局.组件与 ...

  7. JSON Web Token 入门教程

    原文地址:http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html JSON Web Token(缩写 JWT)是目前最流 ...

  8. 在spring中实现quartz2.2.1的动态调度(开始、暂停、停止等)

    参考原文地址: https://blog.csdn.net/fantasic_van/article/details/74942062 一.新建job1 package com.cvicse.ump. ...

  9. 2019年DNS服务器速度排行榜

    第一名:DNSPod 不得不说腾讯自从收购了DNSPod后,无论是服务还是速度都有显著的提升,无论是访问速度还是解析速度都在国内是处于龙头大哥的地位,昔日的老大114的地位已经不保,作为腾讯旗下的公司 ...

  10. 用commander.js构建自己的脚手架工具

    随着前端技术的发展,工程化逐渐成为了一种趋势.但在实际开发时,搭建项目是一件很繁琐的事情,尤其是在对一个框架的用法还不熟悉的时候.于是很多框架都自带一套脚手架工具,在初始化前端项目的时候就可以不用自己 ...