spring boot 学习手册
  • 介绍
  • 基础教程
    • 1.RESTfull API简单项目的快速搭建
    • 2.配置文件详解:Properties和YAML
    • 3.配置文件-多环境配置
    • 4.日志配置-logback和log4j2
  • web应用开发
    • 1.模板引擎
    • 2.模板引擎FreeMarker
    • 3.模板引擎Thymeleaf
    • 4.模板引擎jsp
    • 5.错误处理
    • 6.Servlets, Filters, listeners
    • 7.CORS支持
    • 8.文件上传
    • 9.Interceptor拦截器
    • 10.AOP统一处理Web请求日志
    • 11.全局统一异常处理
    • 12. Retry重试
    • 13.RestTemplate
  • 关系型数据库
    • 1.JdbcTemplate
    • 2.Spring-data-jpa
      • @Id 和 @GeneratedValue 详解
      • 配置与注解备注
      • 全局统一前缀策略
      • 映射关系详解
      • 查询、分页、排序
      • JPA 资料
      • 进阶:jpa自定义行为方法
      • 进阶:锁
      • 进阶:Hibernate Validator
    • 3.事务处理
  • NoSQL数据库
    • 1.Redis
    • 2.Mongodb
  • Cache
    • 1.EhCache
    • 2.Redis
  • 异步消息服务
    • 1.JMS(ActiveMQ)
    • 2.AMQP(RabbitMQ)
  • Mybatis
    • Mybatis 初使用
    • Mybatis环境搭建
    • Mybatis开发流程
    • 业务开发流程
    • Mybatis资料
  • 进阶
    • 1.调用REST服务-使用代理
    • 2.发送邮件
    • 3.Spring Session实现集群-redis
    • 4.如何进行远程调试
    • 5.生产准备-基于HTTP的监控
    • 6.Spring Boot集成mybatis
    • 7.Spring Boot集成Druid
    • 8.Spring Boot集成Swagger
    • 9.生产部署-注意事项和如何使用脚本
  • 升华
    • Jenkins部署Spring Boot
    • 异步处理Http请求
    • FastDFS
    • Docker
    • 定时任务(corn job)
    • 批处理
    • @Async实现异步调用
  • 单元测试
    • WireMock伪造服务
  • 安全
    • 1.Spring Security
      • 认证
    • 2.Apache Shiro
  • TaskExecutor 异步线程池
  • 其他
    • 1.修改启动时显示
    • 2.获取配置文件中的值
    • 3.嵌入式容器
    • 4.配置SSL
    • 5.websocket
    • 6.Spring IO Platform
  • RESTfull API 开发
  • 附录:Eclipse - Spring Tool Suite工具的安装
  • 附录:Eclipse部署Maven
  • 附录:SpringBoot相关模块
  • 附录:注解笔记
  • 资料
  • 开发技巧
  • maven插件
Powered by GitBook
On this page

Was this helpful?

TaskExecutor 异步线程池

Previous2.Apache ShiroNext其他

Last updated 5 years ago

Was this helpful?

spring的TaskExecutor的两个常用实现类均是基于Executor实现类的包装,使其更加方便使用,更好的融入spring bean生态。

controller/HelloController.java

package com.boot.study.controller;

import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.task.TaskExecutor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.boot.study.service.AsyncService;

@RestController
@RequestMapping("/hello")
public class HelloController {

	@Autowired
	private TaskExecutor taskExecutor;

	@GetMapping("/map")
	public Map<String, Object> map() {
		Map<String, Object> map = new HashMap<>();
		map.put("name", "revin");
		map.put("age", 18);

		taskExecutor.execute(new Runnable() {

			@Override
			public void run() {
				try {
					TimeUnit.SECONDS.sleep(3);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}

				System.out.println("我醒了22");
			}
		});

		return map;
	}
}

config/Configs.java

注册配置

package com.boot.study.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

//@EnableAsync
@Configuration
public class Configs {

	@Bean
	public TaskExecutor taskExecutor() {
		ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
		taskExecutor.setCorePoolSize(10);
		taskExecutor.setMaxPoolSize(50);

		return taskExecutor;
	}
}

HelloController.java直接使用了taskExecutor来提交任务,这个时候还需要实现一个Runable的接口来实现具体的任务逻辑。实际上这个过程通过Async注解来进行简化。

Async注解用于表示方法需要异步调用,此时Spring会使用后台的线程池来异步的执行它所注解的方法;一般情况下这个方法的返回类型需要是void的;但也可以是Future类型的;当使用Future时即可对提交的任务执行情况进行判别。

Async注解也可用于类上,当用于类上时,相当于给所有的方法都默认加上了Async注解。

注意使用这个必须在spring Boot中使用Async,EnableAsync,上面configs.java中注释那一行打开,开启异步.

service/AsyncService.java

package com.boot.study.service;

import java.util.concurrent.TimeUnit;

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

@Service
public class AsyncService {

	@Async
	public void hello() {
		try {
			TimeUnit.SECONDS.sleep(3);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		 hello1(); //异步嵌套异步 ,这个异步就不会生效的
		System.out.println("hello aysnc");
	}

	@Async
	public void hello1() {
		try {
			TimeUnit.SECONDS.sleep(3);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		System.out.println("hello1 aysnc");
	}
}

controller/HelloController.java 中应用

package com.boot.study.controller;

import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.task.TaskExecutor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.boot.study.service.AsyncService;

@RestController
@RequestMapping("/hello")
public class HelloController {
	@Autowired
	private AsyncService asyncService;

	@GetMapping
	public String hello() {
		asyncService.hello();
		asyncService.hello1();
		return "hello world";
	}
}

解析:

当异步方法中调用异步方法则不生效的.变成了串行

hello1(); //异步嵌套异步 ,这个异步就不会生效的

则上面的页面访问http://localhost/hello时,页面打印hello world,开始执行两个异步方法,两个同时slepp 3s,

asyncService.hello();
asyncService.hello1();

hello1 sleep 3s后立刻输出, 而 hello中的流程是顺序执行,相当于调用了hello1,在sleep 3s,也就是6s后顺序输出

hello1 aysnc
// 6s 后
hello1 aysnc
hello aysnc

Spring基础学习-任务执行(TaskExecutor及Async)
ExecutorService和TaskExecutor的区别和使用