# TaskExecutor 异步线程池

[Spring基础学习-任务执行（TaskExecutor及Async）](https://blog.csdn.net/icarusliu/article/details/79528810)

[ExecutorService和TaskExecutor的区别和使用](https://www.jianshu.com/p/05b21dca7cf9)

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

controller/HelloController.java

```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

注册配置

```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

```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 中应用

```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后顺序输出

```java
hello1 aysnc
// 6s 后
hello1 aysnc
hello aysnc
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://spring-boot.shujuwajue.com/taskexecutor-yi-bu-xian-cheng-chi.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
