spring boot使用自定义的线程池执行Async任务

2025-05-29 0 30

在前面的博客中,https://www.zzvips.com/article/153013.html 我们使用了spring boot的异步操作,当时,我们使用的是默认的线程池,但是,如果我们想根据项目来定制自己的线程池了,下面就来说说,如何定制线程池!

一、增加配置属性类

?

1

2

3

4

5

6

7

8

9

10
package com.chhliu.springboot.async.configuration;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "spring.task.pool") // 该注解的locations已经被启用,现在只要是在环境中,都会优先加载

public class TaskThreadPoolConfig {

private int corePoolSize;

private int maxPoolSize;

private int keepAliveSeconds;

private int queueCapacity;

…………省略getter,setter方法…………

}

二、创建线程池

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29
package com.chhliu.springboot.async.pool;

import java.util.concurrent.Executor;

import java.util.concurrent.ThreadPoolExecutor;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.scheduling.annotation.EnableAsync;

import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import com.chhliu.springboot.async.configuration.TaskThreadPoolConfig;

@Configuration

@EnableAsync

public class TaskExecutePool {

@Autowired

private TaskThreadPoolConfig config;

@Bean

public Executor myTaskAsyncPool() {

ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();

executor.setCorePoolSize(config.getCorePoolSize());

executor.setMaxPoolSize(config.getMaxPoolSize());

executor.setQueueCapacity(config.getQueueCapacity());

executor.setKeepAliveSeconds(config.getKeepAliveSeconds());

executor.setThreadNamePrefix("MyExecutor-");

// rejection-policy:当pool已经达到max size的时候,如何处理新任务

// CALLER_RUNS:不在新线程中执行任务,而是由调用者所在的线程来执行

executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());

executor.initialize();

return executor;

}

}

三、在主类中开启配置支持

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14
package com.chhliu.springboot.async;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.boot.context.properties.EnableConfigurationProperties;

import org.springframework.scheduling.annotation.EnableAsync;

import com.chhliu.springboot.async.configuration.TaskThreadPoolConfig;

@SpringBootApplication

@EnableAsync

@EnableConfigurationProperties({TaskThreadPoolConfig.class} ) // 开启配置属性支持

public class SpringbootAsyncApplication {

public static void main(String[] args) {

SpringApplication.run(SpringbootAsyncApplication.class, args);

}

}

四、测试类

?

1

2

3

4

5

6

7

8

9

10

11

12

13
package com.chhliu.springboot.async.pool;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.scheduling.annotation.Async;

import org.springframework.stereotype.Component;

@Component

public class AsyncTask {

protected final Logger logger = LoggerFactory.getLogger(this.getClass());

@Async("myTaskAsyncPool") //myTaskAsynPool即配置线程池的方法名,此处如果不写自定义线程池的方法名,会使用默认的线程池

public void doTask1(int i) throws InterruptedException{

logger.info("Task"+i+" started.");

}

}

五、测试

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24
package com.chhliu.springboot.async;

import java.util.concurrent.ExecutionException;

import org.junit.Test;

import org.junit.runner.RunWith;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.test.context.SpringBootTest;

import org.springframework.test.context.junit4.SpringRunner;

import com.chhliu.springboot.async.pool.AsyncTask;

@RunWith(SpringRunner.class)

@SpringBootTest

public class SpringbootAsyncApplicationTests {

protected final Logger logger = LoggerFactory.getLogger(this.getClass());

@Autowired

private AsyncTask asyncTask;

@Test

public void AsyncTaskTest() throws InterruptedException, ExecutionException {

for (int i = 0; i < 100; i++) {

asyncTask.doTask1(i);

}

logger.info("All tasks finished.");

}

}

测试结果如下:

2017-03-20 20:15:15.208 INFO 4068 — [ MyExecutor-10] c.c.springboot.async.pool.AsyncTask : Task60 started.
2017-03-20 20:15:15.208 INFO 4068 — [ MyExecutor-25] c.c.springboot.async.pool.AsyncTask : Task61 started.
2017-03-20 20:15:15.208 INFO 4068 — [ MyExecutor-6] c.c.springboot.async.pool.AsyncTask : Task62 started.
2017-03-20 20:15:15.208 INFO 4068 — [ MyExecutor-23] c.c.springboot.async.pool.AsyncTask : Task63 started.
2017-03-20 20:15:15.208 INFO 4068 — [ MyExecutor-20] c.c.springboot.async.pool.AsyncTask : Task64 started.
2017-03-20 20:15:15.208 INFO 4068 — [ MyExecutor-19] c.c.springboot.async.pool.AsyncTask : Task65 started.
2017-03-20 20:15:15.208 INFO 4068 — [ MyExecutor-16] c.c.springboot.async.pool.AsyncTask : Task66 started.
2017-03-20 20:15:15.208 INFO 4068 — [ MyExecutor-15] c.c.springboot.async.pool.AsyncTask : Task67 started.
2017-03-20 20:15:15.208 INFO 4068 — [ MyExecutor-12] c.c.springboot.async.pool.AsyncTask : Task68 started.
2017-03-20 20:15:15.209 INFO 4068 — [ MyExecutor-1] c.c.springboot.async.pool.AsyncTask : Task69 started.
2017-03-20 20:15:15.209 INFO 4068 — [ MyExecutor-11] c.c.springboot.async.pool.AsyncTask : Task81 started.
2017-03-20 20:15:15.209 INFO 4068 — [ MyExecutor-8] c.c.springboot.async.pool.AsyncTask : Task82 started.
2017-03-20 20:15:15.209 INFO 4068 — [ MyExecutor-7] c.c.springboot.async.pool.AsyncTask : Task83 started.
2017-03-20 20:15:15.209 INFO 4068 — [ MyExecutor-4] c.c.springboot.async.pool.AsyncTask : Task84 started.
2017-03-20 20:15:15.209 INFO 4068 — [ MyExecutor-29] c.c.springboot.async.pool.AsyncTask : Task85 started.
2017-03-20 20:15:15.209 INFO 4068 — [ MyExecutor-21] c.c.springboot.async.pool.AsyncTask : Task86 started.
2017-03-20 20:15:15.209 INFO 4068 — [ MyExecutor-17] c.c.springboot.async.pool.AsyncTask : Task88 started.

测试结果ok!

六、配置默认的线程池

如果我们想使用默认的线程池,但是只是想修改默认线程池的配置,那怎么做了,此时我们需要实现AsyncConfigurer类,示例代码如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47
import java.lang.reflect.Method;

import java.util.concurrent.Executor;

import java.util.concurrent.ThreadPoolExecutor;

import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.annotation.Configuration;

import org.springframework.scheduling.annotation.AsyncConfigurer;

import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import com.chhliu.cq.emailservice.threadconfiguration.TaskThreadPoolConfig;

import lombok.extern.slf4j.Slf4j;

/**

* 注意:该线程池被所有的异步任务共享,而不属于某一个异步任务

* 描述:配置异步任务的线程池

* @author chhliu

* 创建时间:2017年5月22日 上午10:20:56

* @version 1.2.0

*/

@Slf4j

@Configuration

public class AsyncTaskExecutePool implements AsyncConfigurer{

@Autowired

private TaskThreadPoolConfig config; // 配置属性类,见上面的代码

@Override

public Executor getAsyncExecutor() {

ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();

executor.setCorePoolSize(config.getCorePoolSize());

executor.setMaxPoolSize(config.getMaxPoolSize());

executor.setQueueCapacity(config.getQueueCapacity());

executor.setKeepAliveSeconds(config.getKeepAliveSeconds());

executor.setThreadNamePrefix("taskExecutor-");

// rejection-policy:当pool已经达到max size的时候,如何处理新任务

// CALLER_RUNS:不在新线程中执行任务,而是由调用者所在的线程来执行

executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());

executor.initialize();

return executor;

}

@Override

public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {// 异步任务中异常处理

return new AsyncUncaughtExceptionHandler() {

@Override

public void handleUncaughtException(Throwable arg0, Method arg1, Object... arg2) {

log.error("=========================="+arg0.getMessage()+"=======================", arg0);

log.error("exception method:"+arg1.getName());

}

};

}

}

使用的时候,只需在方法上加上@Async即可。

总结

以上所述是小编给大家介绍的spring boot使用自定义的线程池执行Async任务,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对快网idc网站的支持!

原文链接:http://blog.csdn.net/liuchuanhong1/article/details/64132520

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 spring boot使用自定义的线程池执行Async任务 https://www.kuaiidc.com/112616.html

相关文章

发表评论
暂无评论