不灭的焱

革命尚未成功,同志仍须努力下载JDK17

作者:php-note.com  发布于:2022-07-23 17:50  分类:Java框架/系统  编辑

今天来记录一下通过注解来实现异步操作的功能。

在这里我们需要用到两个注解:

  1. @EnableAsync:用来开启异步执行的监听
  2. @Async:用来标注异步方法

通过这两个注解可以很简单的实现异步执行方法 ,也就是开启多线程。

1、在启动类处开启添加@EnableAsync注解

package com.youyou.sso;
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
 
@EnableScheduling
@ServletComponentScan
@SpringBootApplication
@EnableAsync
public class ApiServerApplication {
    
    public static void main(String[] args) {
 
        SpringApplication.run(ApiServerApplication.class, args);
    }
    
}

2、在service处添加@Async注解

package com.youyou.sso.service.impl;
 
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
 
/**
 * //TODO 添加类/接口功能描述
 *
 * @date 2021-10-20
 */
@Service
public class AsyncTestService {
 
//  @Async("asyncServiceExecutor")
    @Async
    public  void test1() throws InterruptedException {
        System.out.println(1);
        Thread.sleep(10000);
        System.out.println(2);
    }
//  @Async("asyncServiceExecutor")
    @Async
    public  void test2() throws InterruptedException {
        System.out.println(3);
        Thread.sleep(10000);
        System.out.println(4);
    }
}

3、测试

package com.youyou.sso.controller;
 
import com.youyou.sso.bean.UserInfo;
import com.youyou.sso.service.ISsoService;
import com.youyou.sso.service.impl.AsyncTestService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
 
import javax.servlet.http.HttpServletRequest;
 
/**
 * //TODO 添加类/接口功能描述
 *
  * @date 2021-09-06
 */
@Api(value = "异步测试", tags = "testAsync")
@RestController("")
@RequestMapping("/testAsync")
public class AsyncTestController {
 
    @Autowired
    private AsyncTestService asyncTestService;
 
    @ApiOperation(value = "|test|")
    @GetMapping("/test")
    public void login() throws InterruptedException {
        asyncTestService.test1();
        asyncTestService.test2();
    }
}

调用此接口时控制台会输出如下:

1
3
4
2

进阶内容

我们可以自己进行线程池的配置

package com.youyou.sso.config;
 
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 java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
 
//@Configuration
//@EnableAsync
public class ExecutorConfig {
 
 
    //    @Bean(name = "asyncServiceExecutor")
//    @Bean
    public Executor executor() {
 
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //配置核心线程数
        executor.setCorePoolSize(5);
        //配置最大线程数
        executor.setMaxPoolSize(5);
        //配置队列大小
        executor.setQueueCapacity(99999);
        //配置线程池中的线程的名称前缀
        executor.setThreadNamePrefix("async-service-");
 
        // rejection-policy:当pool已经达到max size的时候,如何处理新任务
        // CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //执行初始化
        executor.initialize();
        return executor;
    }
 
//    @Bean(name = "asyncServiceExecutor1")
    public Executor asyncServiceExecutor() {
        return executor();
    }
}

在bean注解的name处指定线程池的名字,并且在使用@Async注解时添加此线程池的名字就可以了

 

 

参考:

SpringBoot学习笔记45——通过注解开启线程异步执行方法

SpringBoot如何实现异步处理 四种方式分享