Java异步编程实践
作者:用释怀来成全悲伤_490_905_560 | 来源:互联网 | 2024-12-20 18:02
本文详细介绍了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 ...
[详细]
蜡笔小新 2024-12-27 19:32:17
本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ...
[详细]
蜡笔小新 2024-12-27 18:51:49
本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ...
[详细]
蜡笔小新 2024-12-27 16:07:12
本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ...
[详细]
蜡笔小新 2024-12-27 11:26:39
本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ...
[详细]
蜡笔小新 2024-12-27 19:31:05
本文详细解析了 DotNetNuke (DNN) 的两种主要版本:Community 和 Professional。通过对比两者的功能和附加组件,帮助用户选择最适合其需求的版本。 ...
[详细]
蜡笔小新 2024-12-27 13:14:08
2019独角兽企业重金招聘Python工程师标准一、先在cmake官网下个最新的cmake源码包cmake官网:https:www.cmake.org如此时最新 ...
[详细]
蜡笔小新 2024-12-27 17:49:56
本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ...
[详细]
蜡笔小新 2024-12-27 17:31:41
本文介绍了一款用于自动化部署 Linux 服务的 Bash 脚本。该脚本不仅涵盖了基本的文件复制和目录创建,还处理了系统服务的配置和启动,确保在多种 Linux 发行版上都能顺利运行。 ...
[详细]
蜡笔小新 2024-12-27 16:33:32
本文详细介绍了如何在Ubuntu 16.04 LTS系统中安装和配置Qt Creator,涵盖了从下载到安装的全过程,并提供了常见问题的解决方案。 ...
[详细]
蜡笔小新 2024-12-27 13:19:53
ImmutableX is set to spearhead the evolution of Web3 gaming, with its innovative technologies and strategic partnerships driving significant advancements in the industry. ...
[详细]
蜡笔小新 2024-12-27 08:55:17
本文探讨了如何在模运算下高效计算组合数C(n, m),并详细介绍了乘法逆元的应用。通过扩展欧几里得算法求解乘法逆元,从而实现除法取余的计算。 ...
[详细]
蜡笔小新 2024-12-26 21:41:44
学习链接:http:blog.csdn.netlwt36articledetails48908031学习扫描线主要学习的是一种扫描的思想,后期可以求解很 ...
[详细]
蜡笔小新 2024-12-26 20:04:36
本文详细分析了Hive在启动过程中遇到的权限拒绝错误,并提供了多种解决方案,包括调整文件权限、用户组设置以及环境变量配置等。 ...
[详细]
蜡笔小新 2024-12-26 19:14:29
本文详细介绍了 Java 中的 IO 流,包括字节流和字符流的基本概念及其操作方式。探讨了如何处理不同类型的文件数据,并结合编码机制确保字符数据的正确读写。同时,文中还涵盖了装饰设计模式的应用,以及多种常见的 IO 操作实例。 ...
[详细]
蜡笔小新 2024-12-26 17:37:25
用释怀来成全悲伤_490_905_560
这个家伙很懒,什么也没留下!