认识Java异步@Async
一、认识Java异步
Java中的异步(Asynchronous)指的是一种处理方式,允许程序在执行某个操作时不阻塞当前线程,而是创建一个独立的任务或线程来处理该操作,从而提高并发性和响应性。
在传统的同步编程模型中,当一个操作开始执行时,程序会一直等待操作完成才能继续执行后续的代码。这会导致线程被阻塞,无法同时处理其他的任务,从而降低了程序的并发性和响应性。
而异步编程模型则可以在执行耗时操作时,将控制权返还给调用者,使得调用者可以继续执行其他任务,而不必等待操作的完成。异步操作通常会与回调函数或Future/Promise对象结合使用,以便在操作完成后接收结果或进行进一步处理。
Java提供了多种实现异步编程的方式,包括:
- 线程和Runnable/Callable:通过创建新的线程执行任务,可以使用
Thread类、Runnable接口和Callable接口来实现异步操作。 - Future/Promise:
Future接口和CompletableFuture类可以用于表示一个可能尚未完成的异步操作,并在操作完成后获取结果。 - Callbacks/回调函数:使用回调函数的方式,在异步操作完成时触发回调函数进行处理。可以使用接口、Lambda表达式或函数式编程的方式来定义回调函数。
- Java并发框架:Java提供了并发框架(如ExecutorService、CompletionService等)用于管理线程池和执行异步任务。
二、Java异步使用
1、导入异步支持依赖
<!-- 添加异步依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2、配置线程池
spring:
datasource:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/ttask?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8&useSSL=false
password: root
username: root
task:
execution:
pool:
core-size: 5
max-size: 10
queue-capacity: 100
3、实现类和测试
MyService.java
@Service
public class MyService {
@Async
public void asyncMethod() {
System.out.println("异步方法开始执行,线程:" + Thread.currentThread().getName());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("异步方法执行完毕,线程:" + Thread.currentThread().getName());
}
}
Controler类
@RestController
public class MyAsyncController {
@Autowired
private MyService myService;
@GetMapping("/async")
public String asyncRequest() {
myService.asyncMethod();
return "异步请求已提交";
}
}
注意:在启动类添加@EnableAsync
三、异步应用场景
异步编程在以下场景中特别有用:
- 长时间的IO操作:当程序需要执行像网络请求、数据库查询、文件读写等IO操作时,这些操作通常会阻塞线程并消耗较长时间。使用异步编程可以在发起IO操作后,将控制权返回给调用者,让线程可以同时处理其他任务,待IO操作完成后再通过回调函数或其他方式获取结果。
- 并发处理:当程序需要同时处理多个任务时,可以使用异步编程来提高并发性能。通过将任务分配给不同的线程执行,可以充分利用计算资源,避免任务之间互相阻塞。
- 响应性要求高的应用:对于需要快速响应用户请求的应用程序,异步编程可以提高系统的响应性和吞吐量。例如Web服务器可以使用异步编程来处理大量的并发请求,而不必为每个请求都创建一个新的线程。
- 批量处理:当需要处理大量数据或执行大规模计算时,异步编程可以提高处理速度和效率。通过将任务划分为多个片段,并使用异步方式并行执行这些片段,可以加快整体处理过程。
- GUI应用程序:在图形用户界面(GUI)应用程序中,异步编程可以避免用户界面的阻塞,保持应用程序的响应性。例如,在进行耗时的计算或操作时,可以使用异步方式执行,以允许用户继续与应用程序进行交互。
需要注意的是,在使用异步编程时,需要合理地管理并发性和资源消耗。过度使用异步操作可能会导致代码复杂性增加,出现并发问题或竞争条件。因此,需要根据具体情况仔细评估和设计异步操作的使用场景。