热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Java异步编程实践

本文详细介绍了Java中实现异步调用的多种方式,包括线程创建、Future接口、CompletableFuture类以及Spring框架的@Async注解。通过代码示例和深入解析,帮助读者理解并掌握这些技术。
### 一、使用线程实现异步任务

在Java中,最基本的异步任务实现方式是通过创建新线程来执行耗时操作。下面是一个简单的例子:

```java
@Test
public void testThread() throws Exception {
System.out.println("主线程开始执行");
Thread thread = new Thread(() -> {
System.out.println("===任务开始===");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("===任务完成===");
});
thread.start();
System.out.println("主线程结束执行");
}
```

### 二、Future接口的应用

Future接口用于表示异步计算的结果。它提供了一种检查计算是否完成的方法,并能够获取计算结果或取消计算。然而,Future接口存在一些局限性,例如获取结果时会阻塞主线程。

```java
@Test
public void testFuture() throws Exception {
System.out.println("主线程开始执行");
ExecutorService executor = Executors.newFixedThreadPool(1);
Future future = executor.submit(() -> {
System.out.println("===任务开始===");
Thread.sleep(5000);
System.out.println("===任务完成===");
return 3;
});
// 获取结果时会阻塞主线程
// Integer result = future.get();
System.out.println("主线程结束执行");
executor.shutdown();
}
```

### 三、CompletableFuture类的使用

CompletableFuture类提供了更强大的异步编程能力,支持链式调用和组合多个异步任务。它结合了Future接口的功能,并增加了许多新的特性。

```java
@Test
public void testCompletableFuture() throws Exception {
System.out.println("主线程开始执行");
ExecutorService executor = Executors.newFixedThreadPool(2);
CompletableFuture future = CompletableFuture.supplyAsync(() -> {
System.out.println("===任务开始===");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("===任务完成===");
return 3;
}, executor);
future.thenAccept(System.out::println);
System.out.println("主线程结束执行");
}
```

### 四、Spring框架中的@Async注解

Spring框架提供了@Async注解来简化异步方法的定义。要使用该注解,首先需要在配置类中启用异步支持。

#### XML配置方式

```xml

pool-size="2"
queue-capacity="100"
keep-alive="120"
rejection-policy="CALLER_RUNS" />
```

#### Java配置方式

```java
@Configuration
@EnableAsync
public class AsyncConfig {
@Bean
public TaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(20);
executor.setQueueCapacity(1000);
executor.setKeepAliveSeconds(300);
executor.setThreadNamePrefix("async-thread-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return executor;
}
}
```

#### 使用@Async注解

```java
@Service
public class MyService {
@Async
public void executeLongTask() {
System.out.println("正在执行一项耗时任务");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("任务完成");
}
}

@Test
public void testAsync() throws Exception {
System.out.println("主线程开始执行");
myService.executeLongTask();
System.out.println("主线程结束执行");
}
```

#### 返回值处理

如果异步方法需要返回值,可以使用`AsyncResult`包装返回值。

```java
@Test
public void testAsyncResult() throws Exception {
System.out.println("主线程开始执行");
Future future = myService.executeLongTaskWithResult();
System.out.println("主线程结束执行");
System.out.println("异步执行结果:" + future.get());
}

@Async
public Future executeLongTaskWithResult() {
System.out.println("正在执行一项耗时任务");
try {
Thread.sleep(8000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("任务完成");
return new AsyncResult<>(3);
}
```

推荐阅读
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • DNN Community 和 Professional 版本的主要差异
    本文详细解析了 DotNetNuke (DNN) 的两种主要版本:Community 和 Professional。通过对比两者的功能和附加组件,帮助用户选择最适合其需求的版本。 ... [详细]
  • CentOS7源码编译安装MySQL5.6
    2019独角兽企业重金招聘Python工程师标准一、先在cmake官网下个最新的cmake源码包cmake官网:https:www.cmake.org如此时最新 ... [详细]
  • 本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ... [详细]
  • 本文介绍了一款用于自动化部署 Linux 服务的 Bash 脚本。该脚本不仅涵盖了基本的文件复制和目录创建,还处理了系统服务的配置和启动,确保在多种 Linux 发行版上都能顺利运行。 ... [详细]
  • 在Ubuntu 16.04 LTS上配置Qt Creator开发环境
    本文详细介绍了如何在Ubuntu 16.04 LTS系统中安装和配置Qt Creator,涵盖了从下载到安装的全过程,并提供了常见问题的解决方案。 ... [详细]
  • ImmutableX Poised to Pioneer Web3 Gaming Revolution
    ImmutableX is set to spearhead the evolution of Web3 gaming, with its innovative technologies and strategic partnerships driving significant advancements in the industry. ... [详细]
  • 本文探讨了如何在模运算下高效计算组合数C(n, m),并详细介绍了乘法逆元的应用。通过扩展欧几里得算法求解乘法逆元,从而实现除法取余的计算。 ... [详细]
  • 扫描线三巨头 hdu1928hdu 1255  hdu 1542 [POJ 1151]
    学习链接:http:blog.csdn.netlwt36articledetails48908031学习扫描线主要学习的是一种扫描的思想,后期可以求解很 ... [详细]
  • 本文详细分析了Hive在启动过程中遇到的权限拒绝错误,并提供了多种解决方案,包括调整文件权限、用户组设置以及环境变量配置等。 ... [详细]
  • 从 .NET 转 Java 的自学之路:IO 流基础篇
    本文详细介绍了 Java 中的 IO 流,包括字节流和字符流的基本概念及其操作方式。探讨了如何处理不同类型的文件数据,并结合编码机制确保字符数据的正确读写。同时,文中还涵盖了装饰设计模式的应用,以及多种常见的 IO 操作实例。 ... [详细]
author-avatar
用释怀来成全悲伤_490_905_560
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有