SpringBoot 线程池

释放双眼,带上耳机,听听看~!

配置文件


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
1import org.springframework.context.annotation.Bean;
2import org.springframework.context.annotation.Configuration;
3import org.springframework.core.task.TaskExecutor;
4import org.springframework.scheduling.annotation.EnableAsync;
5import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
6
7import java.util.concurrent.ThreadPoolExecutor;
8@Configuration
9@EnableAsync
10public class ThreadPoolTaskExecutorConfig {
11
12    @Bean
13    public TaskExecutor taskExecutor() {
14        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
15        // 设置核心线程数
16        executor.setCorePoolSize(5);
17        // 设置最大线程数
18        executor.setMaxPoolSize(10);
19        // 设置队列容量
20        executor.setQueueCapacity(20);
21        // 设置线程活跃时间(秒)
22        executor.setKeepAliveSeconds(60);
23        // 设置默认线程名称
24        executor.setThreadNamePrefix("hello-");
25        // 设置拒绝策略
26        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
27        // 等待所有任务结束后再关闭线程池
28        executor.setWaitForTasksToCompleteOnShutdown(true);
29        return executor;
30    }
31}
32

模拟任务,假设每个任务大概需要耗时5S


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1@RestController
2public class Test3Controller {
3
4
5    @GetMapping("/test1")
6    public void  test1() {
7        test();
8    }
9
10    @Async("taskExecutor")
11    public void test() {
12        SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
13        try {
14            Thread.sleep(5000);
15            System.out.println("多线程异步执行" + Thread.currentThread().getName() + "  " + format.format(new Date()));
16        } catch (InterruptedException e) {
17            e.printStackTrace();
18        }
19    }
20}
21

启动类加入注解


1
2
1@EnableAsync
2

我们可以使用jmeter对接口进行并发压力测试【安装教程:https://blog.csdn.net/weixin_44464726/article/details/86152691】

当前线程池所能接受的最大任务数=最大线程数+队列容量

核心线程数=5

同时发送3个请求

SpringBoot 线程池

结论:当线程池小于corePoolSize时,新提交任务将创建一个新线程执行任务,即使此时线程池中存在空闲线程。

同时发送8个请求

SpringBoot 线程池

结论:.当线程池达到corePoolSize时,并且workQueue未满时,新提交任务将被放入workQueue中,等待线程池中任务调度执行

如配置所示,
当前所配置的拒绝策略为:CallerRunsPolicy:

意思是:若当前请求超过最大任务数时,任务将被拒绝并将被直接在execute方法的调用线程中运行被拒绝的任务。

当前最大任务数为30,我给他同时发50个请求

SpringBoot 线程池

可以看到有10个线程在我们自己定义的线程(线程名字为hello)上运行,超出最大线程数并且超出队列的20个线程直接在exec默认线程上运行了,5秒之后,10个线程任务运行完毕,从队列中获取任务去执行,知道队列中所有的任务都已经执行完成。

SpringBoot 线程池

四种拒绝策略:

1、CallerRunsPolicy:让主线程去运行被抛弃掉的任务。好处是能够减缓新任务的提交速度。坏处是很有可能造成当前线程也被阻塞。如果所有线程都是不能执行的,很可能导致程序没法继续跑了。

2、AbortPolicy:jdk默认策略,策略直接抛出异常,丢弃任务。

3、DiscardPolicy:不能执行的任务将被删除,类似AbortPolicy,直接丢弃但不抛异常。

4、DiscardOldestPolicy:丢弃最早的未处理完的线程任务,然后获取下一个任务执行。

可自定义拒绝策略,参考:【https://blog.csdn.net/tanglei6636/article/details/90721801】

给TA打赏
共{{data.count}}人
人已打赏
安全技术

C++ explicit关键字

2022-1-11 12:36:11

安全漏洞

微软发布正则表达式安全漏洞测试工具

2010-10-19 11:12:22

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索