当前位置: 首页 > news >正文

Java中的异步编程模型

1.什么是异步编程?

异步编程是一种编程模式,允许程序在等待某些操作(例如文件I/O或网络请求)完成时,不必停下来等待,而是继续执行其他任务。当异步操作完成时,回调函数或任务调度器会处理结果,从而提高程序的并发性和响应速度。

2.同步 vs 异步

  • 同步:在调用某个方法时,调用方会一直等待该方法执行完毕,才会继续执行后续的操作。期间,调用方被阻塞。
  • 异步:调用某个方法时,调用方可以立即返回,并在方法执行完毕后,通过回调或事件通知的方式处理结果,调用方不会被阻塞。

3.Java中的异步编程工具

Java从java.util.concurrent包开始支持丰富的并发工具,特别是CompletableFuture类,它是异步编程的核心工具。让我们先看看CompletableFuture的基本使用方法。

CompletableFuture:强大的异步任务管理
CompletableFuture是Java 8引入的类,它允许我们轻松地编写异步代码。它不仅可以创建异步任务,还能链式地处理任务结果。

3.1创建异步任务

我们可以通过runAsync()或supplyAsync()方法来创建异步任务。runAsync()适用于不返回结果的任务,而supplyAsync()适用于返回结果的任务。

import java.util.concurrent.CompletableFuture;public class AsyncExample {public static void main(String[] args) {// 创建一个异步任务,模拟计算CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {System.out.println("正在执行异步任务...");try {Thread.sleep(2000);  // 模拟耗时操作} catch (InterruptedException e) {e.printStackTrace();}System.out.println("异步任务完成");});// 主线程继续执行System.out.println("主线程继续执行其他操作...");// 等待异步任务完成future.join();}
}

3.2获取异步任务结果

使用supplyAsync()时,我们可以通过thenApply()方法来处理异步任务的结果。thenApply()接收一个函数,表示任务完成后的处理逻辑。

import java.util.concurrent.CompletableFuture;public class AsyncResultExample {public static void main(String[] args) {// 创建一个返回结果的异步任务CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {System.out.println("正在计算...");return 10 + 20;});// 处理结果future.thenApply(result -> {System.out.println("计算结果: " + result);return result * 2;}).thenAccept(finalResult -> {System.out.println("最终结果: " + finalResult);});// 主线程继续执行System.out.println("主线程继续运行...");}
}

3.3链式处理任务

CompletableFuture的一个强大功能是它允许链式地组合多个异步任务。每个任务可以依赖于上一个任务的结果,从而形成复杂的异步流程。

import java.util.concurrent.CompletableFuture;public class ChainedTasksExample {public static void main(String[] args) {CompletableFuture.supplyAsync(() -> {// 第一个任务System.out.println("任务1: 获取用户数据...");return "用户数据";}).thenApply(userData -> {// 第二个任务,依赖第一个任务的结果System.out.println("任务2: 处理 " + userData);return "处理后的" + userData;}).thenAccept(finalResult -> {// 第三个任务,最终处理结果System.out.println("任务3: 显示结果 " + finalResult);});System.out.println("主线程继续执行...");}
}

3.4处理异常

异步任务中可能会发生异常。CompletableFuture提供了exceptionally()方法来捕获并处理异常,确保程序不会因为某个异步任务的失败而崩溃。

import java.util.concurrent.CompletableFuture;public class ExceptionHandlingExample {public static void main(String[] args) {CompletableFuture.supplyAsync(() -> {// 模拟异常if (true) {throw new RuntimeException("任务失败了");}return 42;}).exceptionally(ex -> {System.out.println("发生异常: " + ex.getMessage());return -1;  // 返回默认值}).thenAccept(result -> {System.out.println("最终结果: " + result);});System.out.println("主线程继续执行...");}
}

4.异步事件驱动模型

除了CompletableFuture,在事件驱动开发中,异步编程也是核心。例如,在处理GUI编程、网络请求、I/O操作时,通常通过异步事件驱动模型来提高系统的响应速度。

在Java中,GUI框架如Swing、JavaFX等,都会使用异步事件模型处理用户输入,避免界面阻塞。

4.1例:JavaFX中的异步事件处理

在JavaFX中,我们可以通过异步任务来避免UI卡顿。例如,当我们需要从网络获取数据时,可以使用异步任务来执行,并在任务完成后更新UI。

import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;public class AsyncJavaFXExample extends Application {@Overridepublic void start(Stage primaryStage) {Label label = new Label("等待中...");StackPane root = new StackPane(label);Scene scene = new Scene(root, 300, 200);primaryStage.setTitle("JavaFX异步任务示例");primaryStage.setScene(scene);primaryStage.show();// 创建异步任务Task<String> task = new Task<String>() {@Overrideprotected String call() throws Exception {// 模拟耗时操作Thread.sleep(2000);return "任务完成";}};// 当任务完成时,更新UItask.setOnSucceeded(event -> label.setText(task.getValue()));// 启动任务new Thread(task).start();}public static void main(String[] args) {launch(args);}
}

独步天涯路自远,我心如铁志如磐。

相关文章:

Java中的异步编程模型

1.什么是异步编程&#xff1f; 异步编程是一种编程模式&#xff0c;允许程序在等待某些操作&#xff08;例如文件I/O或网络请求&#xff09;完成时&#xff0c;不必停下来等待&#xff0c;而是继续执行其他任务。当异步操作完成时&#xff0c;回调函数或任务调度器会处理结果&…...

opencv 按位操作

opencv位运算说明 按位与&#xff0c;按位或&#xff0c;按位非&#xff0c;按位异或 在 OpenCV 中&#xff0c;按位操作函数的接口一般包括两个或多个图像数组&#xff08;矩阵&#xff09;作为输入&#xff0c;常常还会有一个可选的掩码参数。下面我列出每个函数的具体接口…...

【Bug】STM32串口空闲中断接收不定长数据异常

Bug 使用标准库配置STM32F103C8T6的串口1开启接收中断和空闲中断&#xff0c;通过空闲中断来判断数据发送是否结束&#xff0c;收到数据后切换板载LED灯所接引脚电平&#xff0c;发现LED出现三种情况&#xff0c;熄灭、微亮、正常亮&#xff0c;但是LED灯所接的GPIO引脚为PC13…...

使用Radzen Blazor组件库开发的基于ABP框架炫酷UI主题

一、项目简介 使用过ABP框架的童鞋应该知道它也自带了一款免费的Blazor UI主题&#xff0c;它的页面是长这样的&#xff1a; 个人感觉不太美观&#xff0c;于是网上搜了很多Blazor开源组件库&#xff0c;发现有一款样式非常不错的组件库&#xff0c;名叫&#xff1a;Radzen&am…...

Java入门4——输入输出+实用的函数

在本篇博客&#xff0c;采用代码解释的方法&#xff0c;帮助大家熟悉Java的语法 一、输入和输出 在Java当中&#xff0c;我们一般有这样输入输出&#xff1a; import java.util.Scanner;public class javaSchool {public static void main(String[] args) {Scanner scanner …...

《当尼采哭泣》

这是一个相互救赎的故事。故事铺垫比较冗长&#xff0c;看到一半的时候一度看不下去。直到看到最后两章才最终感觉值得一看。很多表层现象&#xff0c;就像露出水面的冰山。解决表面的问题&#xff0c;需要深挖冰山水下的部分。一个人碰到的最难解决的问题不在外部&#xff0c;…...

TOMCAT Using CATALINA——OPTS,闪退解决方法(两种)

【Java实践】安装tomcat启动startup.bat出现闪退问题_安装tomcat点击startup闪退-CSDN博客...

Android音视频 MediaCodec框架-启动编码(4)

Android音视频 MediaCodec框架-启动编码 简述 上一节我们介绍了MediaCodec框架创建编码器流程&#xff0c;编解码的流程其实基本是一样的&#xff0c;只是底层的最终的实现组件不同&#xff0c;所以我们只看启动编码流程。 MediaCodec启动编码 从MediaCodec的start方法开始…...

# Go 语言中的 Interface 和 Struct

go package mainimport ("fmt" )// Girl 是一个接口&#xff0c;定义了所有"女性"类型都应该实现的方法 type Girl interface {call()introduce() }// Wife 结构体代表妻子 type wife struct {name stringage intyearsWed int }// call 方法…...

SSM与Springboot是什么关系? -----区别与联系

SSM&#xff08;Spring Spring MVC MyBatis&#xff09;和 Spring Boot 都是基于 Spring 框架的技术栈&#xff0c;但它们在使用方式、配置复杂度以及设计理念上有所不同。下面是 SSM 和 Spring Boot 之间的关系及主要区别&#xff1a; SSM (Spring Spring MVC MyBatis) 定…...

MATLAB小波变换图像融合系统

二、应用背景及意义 本课题利用小波变换进行图像的融合&#xff0c;然后对融合的结果进行图像质量的评价。所谓小波变换图像融合就是对多个的信息目标进行一系列的图像提取和合成&#xff0c;进而可以获得对同一个信息目标的更为精确、全面、可靠的高低频图像信息描述。并且也…...

nginx-安装和80端口映射多域名和ssl

一、安装所需插件 1、安装 gcc gcc是linux下的编译器&#xff0c;它可以编译 C,C,Ada,Object C和Java等语言。 yum -y install gcc 2、安装pcre、pcre-devel pcre是一个perl库&#xff0c;包括perl兼容的正则表达式库&#xff0c;nginx的http模块使用pcre来解析 正则表达式。…...

SVN小乌龟 create patch 和 apply patch 功能

在SVN&#xff08;Subversion&#xff09;版本控制系统中&#xff0c;使用“小乌龟”&#xff08;TortoiseSVN&#xff09;这个图形界面工具可以极大地简化SVN操作。TortoiseSVN中的“create patch”和“apply patch”是两个非常有用的功能&#xff0c;它们与版本控制中的补丁&…...

#MySQL `SELECT` 语句执行流程详解

在数据库操作中&#xff0c;MySQL 的 SELECT 语句是用于查询数据最常见的 SQL 语句之一。理解它的执行流程对数据库优化和性能提升具有至关重要的意义。本文将详细解析 SELECT 语句从发出请求到返回结果的每个步骤&#xff0c;并结合 MySQL 的架构为您提供深度理解。 ## 1. 连接…...

docker容器运行一段时间提示Failed to initialize NVML: Unknown Error

情况描述 服务器使用docker启动容器。启动以后一切正常也能跑程序。但是&#xff0c;在运行一段时间&#xff08;2天左右不等&#xff09;&#xff0c;会发现gpu掉了。输入nvidia-smi提示 Failed to initialize NVML: Unknown Error 主要发生条件是&#xff0c;docker启动的…...

PPT自动化:快速更换PPT图片(如何保留原图片样式等参数更换图片)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 PPT更换图片 📒1. 安装 `python-pptx` 模块2. 加载PPT文件3. 查找并替换图片3.1 查找图片形状3.2 获取原图片的样式和位置3.3 替换图片4. 保存修改后的PPT文件5. 设置图片的相关参数5.1 设置透明度5.2 设置边框🚀 保留所有参…...

秒懂MVC, MVP, MVVM框架

框架的目标 关注点分离 (separation of concerns)低耦合 (Loose coupling)容易维护 (Maintainable)容易被测试 (Testable)...

IDEA社区版如何用tomcat运行war包

前言 我们在使用IDEA开发Java应用时&#xff0c;有时候需要运行的不是jar包&#xff0c;而是war包&#xff0c;但IDEA社区版默认是不支持tomcat容器的&#xff0c;无法直接运行war包。不过好在我们有一个强大的插件来支持我们使用tomcat&#xff0c;那么&#xff0c;我们应该如…...

如何使用 Git Cherry-Pick 和 Reset 处理误提交,并确保安全回滚

在开发过程中&#xff0c;偶尔会遇到不小心将功能开发提交到错误分支上的情况。假设我们计划在 10 月 24 号上线某些功能&#xff0c;但却不小心在 10 月 17 号的上线分支上进行了开发。为了解决这个问题并将误提交的内容移到正确的分支上&#xff0c;我们可以借助 Git 的一些功…...

Goland 搭建Gin脚手架

一、使用编辑器goland 搭建gin 打开编辑器 新建项目后 点击 create 二、获得Gin框架的代码 命令行安装 go get -u github.com/gin-gonic/gin 如果安装不上&#xff0c;配置一下环境 下载完成 官网git上下载 这样就下载完成了。、 不过这种方法需要设置一下GOPATH 然后再执…...

4大维度掌握全原子蛋白质设计:科研与药企人员的进阶指南

4大维度掌握全原子蛋白质设计&#xff1a;科研与药企人员的进阶指南 【免费下载链接】rf_diffusion_all_atom Public RFDiffusionAA repo 项目地址: https://gitcode.com/gh_mirrors/rf/rf_diffusion_all_atom 核心价值&#xff1a;重新定义蛋白质设计的效率与精度 [突…...

Modbus协议避坑指南:Java处理浮点数数据的3个关键细节

Modbus协议避坑指南&#xff1a;Java处理浮点数数据的3个关键细节 在工业自动化系统中&#xff0c;温度、压力等模拟量的精确采集往往依赖于Modbus协议与PLC设备的稳定通讯。当Java开发者尝试从这些设备读取浮点数数据时&#xff0c;常会遇到数值解析异常、精度丢失或字节序错…...

告别90%无效操作:3个让文档获取效率倍增的反直觉方案

告别90%无效操作&#xff1a;3个让文档获取效率倍增的反直觉方案 【免费下载链接】kill-doc 看到经常有小伙伴们需要下载一些免费文档&#xff0c;但是相关网站浏览体验不好各种广告&#xff0c;各种登录验证&#xff0c;需要很多步骤才能下载文档&#xff0c;该脚本就是为了解…...

四足机器人步态调参实战:如何用Walk These Ways控制器实现楼梯穿越与抗干扰行走

四足机器人步态调参实战&#xff1a;Walk These Ways控制器在复杂地形中的应用技巧 当Unitree Go1机器人第一次站在楼梯前时&#xff0c;开发者们面临着一个经典困境——如何让这台在平地上表现优异的机器跨越这道障碍。传统解决方案往往需要重新训练模型或调整底层算法&#…...

Seata 1.6.1 + Nacos配置避坑指南:Windows环境从安装到整合SpringBoot的完整链路

Seata 1.6.1与Nacos深度整合实战&#xff1a;Windows环境下的全链路配置精要 当微服务架构遇上分布式事务&#xff0c;Seata无疑是Java开发者手中的瑞士军刀。但在Windows环境下&#xff0c;从零搭建Seata服务端到与SpringBoot应用无缝集成&#xff0c;这条路上布满的配置陷阱足…...

3个强力方法解决百度网盘下载限速问题:开源工具实现本地优化加速

3个强力方法解决百度网盘下载限速问题&#xff1a;开源工具实现本地优化加速 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 作为技术探索者&#xff0…...

OpenClaw对比测试:千问3.5-9B与其他模型在自动化任务中的表现

OpenClaw对比测试&#xff1a;千问3.5-9B与其他模型在自动化任务中的表现 1. 测试背景与动机 作为一个长期使用OpenClaw进行个人工作流自动化的技术爱好者&#xff0c;我最近遇到了一个现实问题&#xff1a;当需要处理复杂任务链时&#xff0c;不同的大模型在OpenClaw框架下的…...

从安装到调优:SenseVoiceSmall语音情感识别完整使用指南

从安装到调优&#xff1a;SenseVoiceSmall语音情感识别完整使用指南 1. 引言&#xff1a;为什么选择SenseVoiceSmall&#xff1f; 语音识别技术已经发展到了不仅能听懂我们在说什么&#xff0c;还能感知我们说话时的情绪状态。SenseVoiceSmall作为阿里巴巴达摩院开源的语音理…...

3步找回青春记忆:GetQzonehistory完整导出QQ空间说说终极指南

3步找回青春记忆&#xff1a;GetQzonehistory完整导出QQ空间说说终极指南 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 你是否曾在深夜翻看QQ空间&#xff0c;想要重温那些年写下的心…...

别再手动配IP了!用NI-USRP Configuration Utility快速搞定USRP 2954与LabVIEW连接

告别手动配置&#xff1a;NI-USRP Configuration Utility 快速连接 USRP 2954 与 LabVIEW 全攻略 刚拿到 USRP 2954 设备时&#xff0c;许多工程师和研究人员的第一道坎往往不是复杂的信号处理算法&#xff0c;而是看似基础却令人头疼的网络配置问题。传统的手动 IP 配置方式不…...