总结下Spring boot异步执行逻辑的几种方式

6 篇文章 0 订阅
1 篇文章 0 订阅

概念

  • 异步执行模式:是指语句在异步执行模式下,各语句执行结束的顺序与语句执行开始的顺序并不一定相同。
  • 例如 查询操作,客户机上的应用程序在向服务器发出了查 询操作的指令后,将立刻执行查询语句指令的下一条 语句,而不需要等到服务器将查询结果返回客户机端。异步执行方式使应用程序能摆 脱单个任务的牵制,提高了灵活性和应用程序的执行 效率。但异步执行模式也存在一些问题,如它增加了编程的复杂性,特别是编写互用性(interoperable)要求较高 的程序。
  • 虽然使用异步执行模式在编程序时十分复杂,但可以实现多任务并行执行,使执行的效率大大提高。

这里总结下自己所了解及使用过的可以实现异步执行的几种方式:

实现方式

Thread

直接new Thread()执行方法。

public static void main(String[] args) throws InterruptedException {
    System.out.println("main开始");
    Thread thread = new Thread(() -> {
        System.out.println("子线程执行");
    });
    thread.start();
    Thread.sleep(1000);
    System.out.println("main结束");
}

说明

可以实现异步,但是这种实现会有问题:

  • 每次new Thread() 都会创建新的对象,开销较大,无法复用增加垃圾回收的负担。
  • 每个new Thread() 都是独立的个体,无法有效的管控,无限制创建相互竞争,可能导致oom或者核心业务线程阻塞。
  • 缺乏更多功能,如定时执行、定期执行、线程中断。

Async注解

以spring boot为例,@Async简单使用方法:

  • 启动类中增加@EnableAsync。
  • 方法上面加上@Async。

说明

  • 在方法上使用该@Async注解,申明该方法是一个异步任务;
  • 在类上面使用该@Async注解,申明该类中的所有方法都是异步任务;
  • 使用此注解的方法的类对象,必须是spring管理下的bean对象;
  • 要想使用异步任务,需要在主类上开启异步配置,即,配置上@EnableAsync注解;
  • 在目标方法(说到目标方法,说到 target,说明存在一个代理对象)的签名中,入参是任何类型都支持的。但是,返回类型被限制为 void 或者 Future。所以,异步方法的返回值只能有两种:void 或者 Future。
  • @Async自定义线程池:
    查看该注解可以看到只有一个参数value
    在这里插入图片描述
    这个value属性就是用来传线程池的bean名称的,用于指定线程池。如果@Async不指定任何value值,那么Spring 使用默认的线程池/执行器 去执行这些异步方法,这个默认的执行器就是:SimpleAsyncTaskExecutor。
  • Async失效的场景,可以查看之前的博客:@Async不生效原因

线程池

可以在代码里面显式的创建线程,比如第一种方式,但是如果线程多的话会消耗系统资源,效率
低下并且还会降低系统稳定性。可以看到阿里巴巴编码规范提示:
在这里插入图片描述
所以我们使用线程池提前创建好一些固定的线程数一直在运行状态实现复用,从而可以减少就绪到运行状态的切换。优势是:(不用记知道即可)

  • 降低资源消耗:通过池化技术重复利用已创建的线程,降低线程创建和销毁造成的损耗。
  • 提高响应速度:任务到达时,无需等待线程创建即可立即执行。
  • 提高线程的可管理性:线程是稀缺资源,如果无限制创建,不仅会消耗系统资源,还会因为线程的不合理分布导致资源调度失衡,降低系统的稳定性。使用线程池可以进行统一的分配、调优和监控。
  • 提供更多更强大的功能:线程池具备可拓展性,允许开发人员向其中增加更多的功能。比如延时定时线程池ScheduledThreadPoolExecutor,就允许任务延期执行或定期执行。

代码如下:

在这里插入图片描述
在这里插入图片描述

CompletableFuture(Future及FutureTask)

Future及FutureTask就不说了,直接说完美形态:CompletableFuture,JDK8中新增加了一个包含50个方法左右的类CompletableFuture,提供了非常强大的Future的扩展功能,可以帮助我们简化异步编程的复杂性,提供了函数式编程的能力,可以通过回调的方式处理计算结果,并且提供了转换和组合CompletableFuture的方法。

创建CompletableFuture

// 无返回结果
CompletableFuture<String> completableFuture = new CompletableFuture<>();
// 已知返回结果
CompletableFuture<String> completableFuture = new CompletableFuture<>("result");
// 已知返回结果(底层其实也是带参数的构造器赋值)
CompletableFuture<String> completedFuture = CompletableFuture.completedFuture("result");

异步执行

  • runAsync():runAsync()方法的参数是Runnable接口,这是一个函数式接口,不允许返回值。当需要异步操作且不关心返回结果的时候可以使用runAsync()方法。
  • supplyAsync():supplyAsync()方法的参数是Supplier供给型接口(无参有返回值),这也是一个函数式接口,U是返回结果值的类型。当需要异步操作且关心返回结果的时候,可以使用supplyAsync()方法。

消息队列

基于队列与消息传递技术,在网络环境中为应用系统提供同步或异步、可靠的消息传输的支撑性软件系统 。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Spring Boot支持多线程编程,主要有以下几种方式: 1. 继承Thread类或实现Runnable接口 这是最基本的多线程编程方式,可以在Spring Boot中使用。开发者可以通过继承Thread类或实现Runnable接口,重写run()方法实现多线程逻辑。示例代码: ```java public class MyThread extends Thread { @Override public void run() { // 多线程逻辑 } } public class MyRunnable implements Runnable { @Override public void run() { // 多线程逻辑 } } // 使用 new MyThread().start(); new Thread(new MyRunnable()).start(); ``` 2. 使用线程池 线程池可以有效地管理多个线程,避免创建和销毁线程的开销。Spring Boot提供了ThreadPoolTaskExecutor类,可以用来创建和管理线程池。示例代码: ```java @Configuration @EnableAsync public class AsyncConfig implements AsyncConfigurer { @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(10); executor.setMaxPoolSize(20); executor.setQueueCapacity(30); executor.initialize(); return executor; } } // 使用 @Async public void doSomething() { // 多线程逻辑 } ``` 3. 使用CompletableFuture CompletableFuture是Java 8引入的异步编程方式,可以很方便地实现多线程编程。Spring Boot也提供了对CompletableFuture的支持。示例代码: ```java public CompletableFuture<String> doSomething() { CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { // 多线程逻辑 return "result"; }); return future; } ``` 以上是Spring Boot中多线程编程的三种方式,开发者可以根据具体的业务场景选择不同的方式。 ### 回答2: Spring Boot是一个用于快速构建基于Spring框架的应用程序的工具。在Spring Boot中,可以轻松地实现多线程的功能。 Spring Boot提供了多种方式来实现多线程。一种常用的方式是使用`@Async`注解来标记一个方法异步方法。在使用`@Async`注解之后,该方法将会在一个单独的线程中执行,而不会阻塞主线程。通过使用这个注解,可以在应用程序中执行耗时操作,而不会影响其他的业务逻辑。需要注意的是,要实现异步方法,还需要在应用程序的主类上添加`@EnableAsync`注解。 除了使用`@Async`注解外,Spring Boot还提供了`ThreadPoolTaskExecutor`类来方便地创建线程池。通过配置线程池的大小、最大线程数等参数,可以实现更加灵活和高效的多线程处理。可以在应用程序的配置文件中添加以下配置来创建线程池: ```java @Configuration @EnableAsync public class AsyncConfig { @Bean(name = "taskExecutor") public Executor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(5); executor.setMaxPoolSize(10); executor.setQueueCapacity(25); executor.setThreadNamePrefix("taskExecutor-"); executor.initialize(); return executor; } } ``` 上述配置创建了一个线程池,核心线程数为5,最大线程数为10,队列容量为25。通过将`@Async`注解和`taskExecutor`作为参数添加到方法中,即可实现多线程的功能。 综上所述,Spring Boot提供了多种方式来实现多线程。使用`@Async`注解可以快速实现异步方法,而`ThreadPoolTaskExecutor`类则提供了更加灵活和高效的线程池配置。这些功能可以帮助我们提高应用程序的性能和并发处理能力。 ### 回答3: Spring Boot多线程允许开发者在应用程序中使用并发处理来提高性能和效率。它基于Java的多线程机制,但通过Spring Boot可以更加方便地进行配置和管理。 Spring Boot使用了Java的Executor框架来处理线程池和线程管理。开发者可以通过@EnableAsync注解启用异步方法和@Async注解将方法标记为异步执行。这样在调用该方法时,Spring Boot会自动创建一个新的线程执行方法,而当前线程则不会被阻塞。 使用多线程可以提高应用程序的响应性能,特别是在处理一些耗时的操作时。通过异步方法,可以将一些需要等待的操作转移到后台线程中执行,不影响主线程继续执行其他操作。这对于处理大量请求或者IO密集型的任务非常有用。 在配置多线程时,开发者可以指定线程池的大小、最大线程数、线程的生命周期等参数。这些参数可以根据具体的应用场景进行调整,以达到最佳的性能和资源利用。同时,Spring Boot还提供了一些方便的工具类和注解,用于处理线程间的数据共享和同步,如通过ThreadLocal存储线程局部变量,通过@Lock注解实现对指定资源的加锁。 总之,Spring Boot多线程提供了一种便捷的方式来管理并发处理,使得开发者能够更加轻松地实现并行执行异步操作。它可以大大提高应用程序的性能和响应能力,适用于处理一些耗时的任务和IO密集型的操作。但同时也需要注意线程安全和资源管理的问题,合理配置和使用多线程,才能充分发挥其潜力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰红茶不会渴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值