SpringBoot-09

Async是什么

    Async(异步)是一种编程概念,用于指示程序在执行某个操作时可以同时执行其他任务,而不需要等待该操作完成。在传统的同步编程中,程序会按顺序执行每个操作,并在当前操作完成后再执行下一个操作。而在异步编程中,程序可以在执行一个操作时,立即转而执行其他操作,而不需要等待该操作完成。

异步编程常用于处理耗时的操作,如网络请求、文件读写、数据库操作等。通过异步机制,程序可以在等待操作完成时,继续执行其他任务,从而提高程序的整体性能和响应速度。

异步编程可以使用多种方式实现,常见的有回调函数、Promise、async/await等。这些机制可以使程序在执行异步操作时,以更简洁和易读的方式编写代码。

Async异步调用方法

     异步调用是指在调用一个方法时,不会等待方法执行完成再继续执行下面的代码,而是立即返回,然后在后台线程中执行该方法。以下是异步调用方法的详细步骤:
  1. 创建一个异步任务(也可以称为线程),用于执行需要异步执行的方法。这可以通过创建一个新的线程对象或使用线程池来实现。

  2. 将需要异步执行的方法包装在一个函数或方法中,并将其作为参数传递给异步任务。这个函数或方法通常被称为回调函数。

  3. 异步任务启动后,立即返回,并允许主线程继续执行后面的代码。

  4. 异步任务在后台线程中执行回调函数,完成相应的操作。

  5. 当回调函数执行完成后,异步任务通常会给主线程发送一个通知,以便主线程可以处理异步任务的结果。

  6. 主线程在接收到异步任务完成的通知后,可以获取异步任务的结果,并根据需要进行后续处理。

需要注意的是,在使用异步调用时,如果需要获取异步任务的结果,可以使用异步任务返回一个Future对象或通过回调函数的参数传递结果。

启用异步支持

首先,需要在主应用类或配置类上添加 `@EnableAsync` 注解,以启用 Spring 的异步方法支持:


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;

@SpringBootApplication
@EnableAsync
public class YourApplication {
    public static void main(String[] args) {
        SpringApplication.run(YourApplication.class, args);
    }
}

 创建异步方法

在需要异步执行的方法上使用 `@Async` 注解。方法的返回类型通常是 `Future<T>`、`CompletableFuture<T>` 或 `ListenableFuture<T>`,这取决于你需要的异步特性。

示例:使用 `CompletableFuture`


import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.concurrent.CompletableFuture;

@Service
public class YourService {

    @Async
    public CompletableFuture<String> performAsyncOperation() {
        // 模拟耗时操作
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return CompletableFuture.completedFuture("Operation Completed");
    }
}

调用异步方法

在调用异步方法时,你可以使用返回的 `CompletableFuture` 来获取结果或处理异常:


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 java.util.concurrent.CompletableFuture;

@RestController
@RequestMapping("/api")
public class YourController {

    @Autowired
    private YourService yourService;

    @GetMapping("/async-operation")
    public CompletableFuture<String> performOperation() {
        return yourService.performAsyncOperation();
    }
}

 配置线程池(可选)

默认情况下,Spring 使用一个简单的线程池来执行异步方法。你可以自定义线程池配置来优化异步任务的执行:


import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;

@Configuration
@EnableAsync
public class AsyncConfig {

    @Bean(name = "taskExecutor")
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5); // 核心线程数
        executor.setMaxPoolSize(10); // 最大线程数
        executor.setQueueCapacity(100); // 队列容量
        executor.setThreadNamePrefix("Async-");
        executor.initialize();
        return executor;
    }
}

在这个配置类中,你可以设置线程池的核心线程数、最大线程数、队列容量等参数,以适应你的应用需求。

异步方法的异常处理

在异步方法中抛出的异常不会被直接捕获,你需要在返回的 `CompletableFuture` 上处理异常:


import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.concurrent.CompletableFuture;

@Service
public class YourService {

    @Async
    public CompletableFuture<String> performAsyncOperation() {
        return CompletableFuture.supplyAsync(() -> {
            try {
                // 模拟耗时操作
                Thread.sleep(2000);
                // 模拟异常
                if (true) throw new RuntimeException("Something went wrong");
                return "Operation Completed";
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
    }
}

你可以使用 `CompletableFuture` 的 `exceptionally` 方法来处理异常:


@RestController
@RequestMapping("/api")
public class YourController {

    @Autowired
    private YourService yourService;

    @GetMapping("/async-operation")
    public CompletableFuture<String> performOperation() {
        return yourService.performAsyncOperation()
                .exceptionally(ex -> "Error occurred: " + ex.getMessage());
    }
}

总结

    Async异步调用是指在调用某个方法时,不阻塞当前线程,而是在另一个线程中执行该方法,并在完成后返回结果或回调函数。

使用Async异步调用的优点:

  1. 提高系统的并发性能:通过将耗时的操作放到另一个线程中执行,可以使得主线程不被阻塞,从而提高系统的并发性能。
  2. 改善用户体验:用户不会因为长时间地等待而感到不满,可以继续做其他操作。
  3. 避免阻塞I/O操作:在I/O操作中,由于需要等待数据的读取或传输,会导致线程被阻塞。使用Async异步调用可以避免这种情况,提高程序效率。

在Java中,可以使用以下方式进行Async异步调用:

  1. 使用Thread类:可以创建一个新的线程来执行耗时操作,并使用join()方法等待线程执行完成。
  2. 使用ExecutorService和Future:通过ExecutorService.submit()方法提交一个Callable或Runnable对象来执行耗时操作,并使用Future.get()方法获取结果或回调函数。
  3. 使用CompletableFuture:CompletableFuture类提供了一种更灵活和强大的方式来进行异步操作,可以使用thenCompose()、thenApply()、thenAccept()等方法来组合多个异步操作。

需要注意的是,虽然Async异步调用可以提高系统的并发性能,但同时也需要考虑线程安全性和资源管理。在使用Async异步调用时,应该注意合理地控制并发线程的数量,避免资源竞争和死锁等问题。

  • 17
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值