SpringBoot实现多线程

2022-07-17 11:29:20

SpringBoot实现多线程

  1. SpringBoot通过任务执行器TaskExecutor来实现多线程和并发编程。
  2. 使用TreadPoolTaskExecutor可实现一个基于线程池的TaskExecutor
  3. 实际开发任务一般是非阻碍的,即异步的,所以我们要在配置类中通过@EnableAsync开启对异步任务的支持,并通过在实际执行的Bean中的方法使用@Async注解来声明这是一个异步任务

0. 同步和异步

  • 同步交互:指发送一个请求,需要等待返回,然后才能够发送下一个请求,有个等待过程;

  • 异步交互:指发送一个请求,不需要等待返回,随时可以再发送下一个请求,即不需要等待。

区别:一个需要等待,一个不需要等待。在部分情况下,我们的项目开发中都会优先选择不需要等待的异步交互方式

1. 引入 Maven 依赖

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><version>2.4.4</version></dependency></dependencies>

2. 异步执行的配置类 AsyncConfig

package com.melodyjerry.thread;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;import java.util.concurrent.Executor;/**
 * @classname AsyncConfig
 * @description 开启异步执行的配置类
 */@Configuration@EnableAsync//开启异步执行@ComponentScan("com.melodyjerry.thread")publicclassAsyncConfigimplementsAsyncConfigurer{@Overridepublic ExecutorgetAsyncExecutor(){
        ThreadPoolTaskExecutor threadPoolTaskExecutor=newThreadPoolTaskExecutor();//线程池中的线程的名称前缀
        threadPoolTaskExecutor.setThreadNamePrefix("SpringBoot线程池的前缀-");//线程池的核心线程数大小
        threadPoolTaskExecutor.setCorePoolSize(4);//线程池的最大线程数
        threadPoolTaskExecutor.setMaxPoolSize(8);//等待队列的大小
        threadPoolTaskExecutor.setQueueCapacity(25);//执行初始化
        threadPoolTaskExecutor.initialize();return threadPoolTaskExecutor;}}

3. 异步任务的执行类

package com.melodyjerry.thread;import org.springframework.scheduling.annotation.Async;import org.springframework.stereotype.Service;/**
 * @classname AsyncTaskService
 * @description 异步任务的执行类
 */@ServicepublicclassAsyncTaskService{@Async//异步方法publicvoidexecuteAsyncTask(Integer i){
        System.out.println("执行异步任务: "+i);}@Async//异步方法publicvoidexecuteAsyncTaskPlus(Integer i){
        System.out.println("执行异步任务+1: "+(i+1));}}
  • @Async注解表明该方法是个异步方法

  • 从Async注解接口可以看到,Target即可以在方法也可以在类型上,如果注解在类型上,表明该类所有的方法都是异步方法。

在这里插入图片描述

4. 测试效果 TestThreadApplication

package com.melodyjerry.thread;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.ConfigurableApplicationContext;/**
 * @classname TestThreadApplication
 * @description 测试异步任务
 */@SpringBootApplicationpublicclassTestThreadApplication{publicstaticvoidmain(String[] args){
        ConfigurableApplicationContext context= SpringApplication.run(TestThreadApplication.class, args);

        AsyncTaskService asyncTaskService= context.getBean(AsyncTaskService.class);for(int i=0; i<10; i++){
            asyncTaskService.executeAsyncTask(i);
            asyncTaskService.executeAsyncTaskPlus(i);}
        System.out.println("This Program has Begun successfully");}}
This Program has Begun successfully
执行异步任务: 0
执行异步任务: 2
执行异步任务+1: 1
执行异步任务+1: 3
执行异步任务: 3
执行异步任务: 4
执行异步任务+1: 5
执行异步任务: 5
执行异步任务+1: 6
执行异步任务+1: 2
执行异步任务: 6
执行异步任务+1: 4
执行异步任务: 7
执行异步任务: 8
执行异步任务+1: 9
执行异步任务: 9
执行异步任务+1: 10
执行异步任务+1: 7
执行异步任务+1: 8
执行异步任务: 1
  • 作者:喜欢前端的后端MelodyJerry
  • 原文链接:https://melodyjerry.blog.csdn.net/article/details/116108860
    更新时间:2022-07-17 11:29:20