首页 > 其他分享 >异步注解@Async使用记录

异步注解@Async使用记录

时间:2023-02-15 11:01:04浏览次数:34  
标签:异步 import System 线程 注解 println Async out

使用场景:需要执行某个方法但不需等待该方法的执行结果或者需要执行多个方法但这些方法不需要先后执行,可以通过声明并调用异步方法实现.因为每执行一个异步方法都需要从线程池中申请并占用一个线程,为避免线程资源过度损耗,需要自行维护线程池。

 

1 启动类上加 @EnableAsync 表示开启异步注解

2 controller:调用异步方法:调用无返回值的异步方法时,无需等待其执行结束;对于有返回值的异步方法时,获取其返回值时,需要同步等待

package kun.async;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;


@RestController
public class AsyncController {
    @Autowired
    private AsyncService asyncService;

    @GetMapping("/async-task")
    public void doAsyncTask() {
        System.out.println("doAsyncTask begin");
        asyncService.asyncInVoid();
        System.out.println("doAsyncTask end");
    }

    @GetMapping("/async-task-with-result")
    public Integer doAsyncTaskWithResult() {
        System.out.println("doAsyncTaskWithResult begin");
        Future<Integer> result = asyncService.asyncWithResult();
        try{
            System.out.println("doAsyncTaskWithResult end");
            return result.get();
        } catch (ExecutionException | InterruptedException ex) {
            throw new RuntimeException("execute failed");
        }
    }

    @GetMapping("/async-task-with-result-2")
    public Integer doAsyncTaskWithResult2() {
        System.out.println("doAsyncTaskWithResult2 begin");
        Future<Integer> result = asyncService.asyncWithResult();
        try{
            System.out.println("doAsyncTaskWithResult end");
            Thread.sleep(15000);
            // get()方法会一直阻塞,方法最后的执行时间,依赖执行时间最长的线程
            return result.get();
        } catch (ExecutionException | InterruptedException ex) {
            throw new RuntimeException("execute failed");
        }
    }
}

3 service,声明异步方法

package kun.async;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import java.util.concurrent.Future;

@Service
@Slf4j
public class AsyncService {
    /**
     * 异步调用示例,无返回值
     */
    @Async
    public void asyncInVoid() {
        System.out.println("asyncInVoid begin");
        try {
            Thread.sleep(5000);
            System.out.println("current time is: " + System.currentTimeMillis());
        } catch (InterruptedException ex) {
            log.error("thread sleep failed: ", ex);
        }
        System.out.println("asyncInVoid end");
    }

    /**
     * 异步调用示例,有返回值
     *
     * @return
     */
    @Async
    public Future<Integer> asyncWithResult() {
        System.out.println("asyncWithResult begin");
        try {
            Thread.sleep(10000);
            System.out.println("current time is: " + System.currentTimeMillis());
        } catch (InterruptedException ex) {
            log.error("thread sleep failed: ", ex);
        }
        System.out.println("asyncWithResult end");
        return new AsyncResult<Integer>(1000);
    }
}

4 自定义异步方法调用线程池

异步方法运行在独立的线程中,不会阻塞主线程的执行。异步方法执行所需的线程默认是从SpringBoot提供线程池中申请线程。为控制线程的使用和回收,商用环境一般使用自定义线程池,以保证异步方法的调用可控。SpringBoot提供AsyncTaskExecutor用于实现自定义异步方法调用线程池。示例代码如下:

@Configuration
public class AsyncConfig {
    private static final int MAX_POOL_SIZE = 50;
    private static final int CORE_POOL_SIZE = 20;
    private static final int WAIT_QUEUE_CAPACITY = 1000;

    @Bean("taskExecutor")
    public AsyncTaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setThreadNamePrefix("async-task-thread-pool-");
        taskExecutor.setMaxPoolSize(MAX_POOL_SIZE);
        taskExecutor.setCorePoolSize(CORE_POOL_SIZE);
        taskExecutor.setQueueCapacity(WAIT_QUEUE_CAPACITY);
        taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        taskExecutor.initialize();
        return taskExecutor;
    }
}

 

标签:异步,import,System,线程,注解,println,Async,out
From: https://www.cnblogs.com/1--2/p/17122001.html

相关文章

  • 彻底搞懂同步异步与阻塞非阻塞
    上两篇文章讲过了BIO与非阻塞IO以及IO多路复用,洋洋洒洒近3万字。这篇文章我们来聊一个很简单,但是很多人往往分不清的一个问题,同步异步、阻塞非阻塞到底怎么区分?开篇先问......
  • .Net6对AOP的多种支持之IAsyncActionFilter
    环境:  .Net6  windows10  Web项目 ps:Log4net写入到文件以及写入到数据库中开发工具:Vs2022IAsyncActionFilter(日志异步实现) IAsynctionFilter概念......
  • Python 异步: 当前和正在运行的任务(9)
    我们可以反省在asyncio事件循环中运行的任务。这可以通过为当前运行的任务和所有正在运行的任务获取一个asyncio.Task对象来实现。1.如何获取当前任务我们可以通过......
  • SpringBoot常用注解大全
    常用注解概览这里整理了一张SpringBoot常用注解的思维导图,本文主要讲解这些注解的用法。 组件相关注解@ComponentScan默认扫描当前包及其子包下面被@component,@Cont......
  • spring-注解开发
    一.注解实现自动装配jdk1.5开始支持注解,spring2.5开始支持注解!要使用注解须知:1.导入约束xmlns:context="http://www.springframework.org/schema/context"http://......
  • 三相异步电动机改作发电机运行小结
    1、我用三相异步电动机并联电容的方式做发电机可以吗?如果用50千瓦的异步电动机需多大的电容,发出的功率有多少?50千瓦电动机大概需要300UF电容。发出的功率40千瓦。2、......
  • 注解和反射
    注解和反射1、注解(Annotation)作用:​ 不是程序本身,可以对程序作出解释​ 可以被其他程序(编译器)读取格式:​ 注解是以“@注释名”在代码中存在的,还可以添加一些参数值......
  • @Bean注解和@Resource注解的用法作用
    今天学习Hikari资源池,想对资源池的一些参数进行监听时,不知道使用什么方法,然后查阅资料得知通过创建配置类,在配置类里对HikariDataSource进行初始化,通过@Bean创建bean交给sp......
  • SpringBoot注解大全
    一、项目配置注解@SpringBootApplication:申明让springboot自动给程序进行必要的配置,这个配置等同于:@Configuration ,@EnableAutoConfiguration 和@ComponentScan 三个......
  • 【学习笔记】Spring注解开发
    Spring注解开发使用注解开发首先要导入context约束,然后开启注解支持<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/bea......