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

实现异步的8种方式,你知道几个?

  • 一、前言

    在编程中,有时候我们需要处理一些费时的操作,比如网络请求、文件读写、数据库操作等等,这些操作会阻塞线程,等待结果返回。为了避免阻塞线程、提高程序的并发处理能力,我们常常采用异步编程。

    异步编程是一种编程方式,它通过将任务提交给其他线程或者线程池来实现并发处理,从而提高程序的性能和响应速度。

    本文将介绍异步的八种实现方式,并详细阐述异步编程的概念、实现方式和优缺点等问题。

    二、异步的八种实现方式

    异步编程的实现方式有很多种,下面是常见的八种实现方式:

    1. 线程异步
    2. Future异步
    3. CompletableFuture实现异步
    4. Spring的@Async异步
    5. Spring ApplicationEvent事件实现异步
    6. 消息队列
    7. ThreadUtil异步工具类
    8. Guava异步

    不同的实现方式适用于不同的场景,我们需要根据具体的需求来选择合适的实现方式。

    三、什么是异步?

    在讲解异步编程之前,我们先来了解一下异步的概念。

    异步是指不需要等待当前操作完成,就能够进行其他操作。例如,我们发出一个网络请求后,可以继续执行其他任务,不必等待网络请求返回结果再执行其他任务,这就是异步操作。

    异步的本质是将任务提交给其他线程或者线程池来处理,等待结果时,当前线程不会被阻塞,可以继续处理其他任务。

    四、异步编程

    异步编程是通过将耗时的任务分配给其他线程或者线程池来实现的,可以提高程序的并发处理能力,让程序具有更好的性能和响应速度。

    下面我们将介绍异步编程的八种实现方式。

    4.1 线程异步

    线程异步是一种最为基础的异步实现方式,它通过创建一个新的线程来执行耗时操作,从而避免阻塞主线程。

    线程异步的示例代码如下:

    public void doAsyncTask() {Thread thread = new Thread(() -> {// 耗时操作doHeavyTask();});thread.start();
    }private void doHeavyTask() {// 耗时操作// ...
    }
    

    4.2 Future异步

    Future异步是通过使用Java的Future接口来实现的,它提供了异步编程的基础能力。

    Future异步的示例代码如下:

    public void doAsyncTask() {ExecutorService executorService = Executors.newCachedThreadPool();Future<Result> future = executorService.submit(() -> {// 耗时操作return doHeavyTask();});// 在这里处理异步操作的结果try {Result result = future.get();handleResult(result);} catch (Exception e) {handleError(e);}
    }private Result doHeavyTask() {// 耗时操作// ...return new Result();
    }private void handleResult(Result result) {// 处理异步操作的结果// ...
    }private void handleError(Exception e) {// 处理异步操作的异常// ...
    }
    

    4.3 CompletableFuture实现异步

    CompletableFuture是Java 8中引入的一个异步编程工具类,它提供了更加方便的异步编程方式。

    CompletableFuture实现异步的示例代码如下:

    public void doAsyncTask() {CompletableFuture<Result> future = CompletableFuture.supplyAsync(() -> {// 耗时操作return doHeavyTask();});// 处理异步操作的结果future.thenAccept(this::handleResult).exceptionally(this::handleError);
    }private Result doHeavyTask() {// 耗时操作// ...return new Result();
    }private void handleResult(Result result) {// 处理异步操作的结果// ...
    }private void handleError(Throwable throwable) {// 处理异步操作的异常// ...
    }
    

    4.4 Spring的@Async异步

    Spring框架提供了@Async注解来实现异步编程,它可以将一个方法标记为异步执行,并使用ThreadPoolTaskExecutor来执行耗时操作。

    Spring的@Async异步的示例代码如下:

    @Service
    public class MyService {@Asyncpublic void doAsyncTask() {// 耗时操作doHeavyTask();}private void doHeavyTask() {// 耗时操作// ...}
    }
    

    4.5 Spring ApplicationEvent事件实现异步

    Spring还提供了ApplicationEvent异步事件,可以在事件监听器中处理耗时操作,从而实现异步编程。

    Spring ApplicationEvent事件实现异步的示例代码如下:

    @Component
    public class MyEventListener {@EventListener@Asyncpublic void handleEvent(MyEvent event) {// 耗时操作doHeavyTask();}private void doHeavyTask() {// 耗时操作// ...}
    }
    

    4.6 消息队列

    消息队列是一种基于异步消息传递的异步编程方式,它将消息放入队列中,异步处理这些消息。

    常见的消息队列有ActiveMQ、RabbitMQ、RocketMQ等等。

    消息队列的示例代码如下:

    public void doAsyncTask() {// 发送异步消息sendAsyncMessage();// 处理其他任务// ...
    }private void sendAsyncMessage() {// 将消息发送到消息队列中// ...
    }
    

    4.7 ThreadUtil异步工具类

    ThreadUtil是一个Java工具类,提供了很多方便的异步编程方法,例如:线程池、定时器、异步调度等等。

    ThreadUtil异步工具类的示例代码如下:

    public void doAsyncTask() {// 使用线程池执行异步任务ThreadUtil.execAsync(() -> {// 耗时操作doHeavyTask();});// 处理其他任务// ...
    }private void doHeavyTask() {// 耗时操作// ...
    }
    

    4.8 Guava异步

    Guava是一个Google开发的Java工具类库,提供了很多常用的工具类和方法,其中包括异步编程的实现方式。

    Guava异步的示例代码如下:

    public void doAsyncTask() {ListenableFuture<Result> future = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool()).submit(() -> {// 耗时操作return doHeavyTask();});Futures.addCallback(future, new FutureCallback<Result>() {@Overridepublic void onSuccess(@Nullable Result result) {handleResult(result);}@Overridepublic void onFailure(Throwable throwable) {handleError(throwable);}});
    }private Result doHeavyTask() {// 耗时操作// ...return new Result();
    }private void handleResult(Result result) {// 处理异步操作的结果// ...
    }private void handleError(Throwable throwable) {// 处理异步操作的异常// ...
    }
    

    以上就是异步编程的八种实现方式,它们各有优缺点,我们需要根据具体的需求来选择合适的实现方式。

相关文章:

实现异步的8种方式,你知道几个?

一、前言 在编程中&#xff0c;有时候我们需要处理一些费时的操作&#xff0c;比如网络请求、文件读写、数据库操作等等&#xff0c;这些操作会阻塞线程&#xff0c;等待结果返回。为了避免阻塞线程、提高程序的并发处理能力&#xff0c;我们常常采用异步编程。 异步编程是一种…...

二叉树的三种遍历

二叉树的遍历可以有&#xff1a;先序遍历、中序遍历、后序遍历先序遍历&#xff1a;根、左子树&#xff0c;右子树中序遍历&#xff1a;左子树、根、右子树后序遍历&#xff1a;左子树、右子树、根下面是我画图理解三种遍历&#xff1a;二叉树里都是分为左子树和右子树。分治思…...

我,30岁程序员被裁了,千万别干全栈

大家好&#xff0c;这里是程序员晚枫&#xff0c;今天是读者投稿。下面开始我们的正文。&#x1f447; 关注博主&#x1f449;程序员晚枫 很久了&#xff0c;今天给大家分享一下我从事程序员后&#xff0c;30岁被裁的经历&#xff0c;希望帮到有需要的人。 1、我被裁了 大家好…...

【linux】:进程地址空间

文章目录 前言一、进程地址空间总结前言 本篇文章接着上一篇文章继续讲解进程&#xff0c;主要讲述了进程在运行过程中是如何在内存中被读取的以及为什么要有虚拟地址的存在&#xff0c;CPU在运行过程中是拿到程序的虚拟地址还是真实的物理内存。 一、进程地址空间 下面我们先…...

【保姆级】JMeter Mqtt 压测配置

忽然有个紧急任务要对某个服务做MQTT做压测&#xff0c;紧急实操下JMeter&#xff0c;这里记录下非专业测试员的测试过程、(▽&#xff40;)&#xff0c;欢迎&#x1f44f;大家检查指点(&#xffe3;∇&#xffe3;)/下载⏬工具JMeter官方下载地址https://jmeter.apache.org/do…...

C语言数据结构初阶(4)----带头双向循环链表

我们先来看看带头双向循环链表的结构&#xff1a;看到这里我们可能会产生一个想法&#xff1a;这个链表看起来好复杂的样子&#xff0c;是不是它的增删改查比单链表更难写呢&#xff1f;嘿嘿&#xff0c;还真的不是这样的&#xff0c;双向链表的增删改查是很好写的哦&#xff0…...

原生javascript手写一个丝滑的轮播图

通过本文&#xff0c;你将学到: htmlcssjs 没错&#xff0c;就是html&#xff0c;css,js,现在是框架盛行的时代&#xff0c;所以很少会有人在意原生三件套&#xff0c;通过本文实现一个丝滑的轮播图&#xff0c;带你重温html,css和js基础知识。 为什么选用轮播图做示例&…...

【Linux】进程优先级(进程优先级 Linux下优先级 用top命令更改已存在进程的nice 其他概念 进程切换)

文章目录进程优先级Linux下优先级用top命令更改已存在进程的nice&#xff1a;其他概念进程切换进程优先级 我们作为使用者一般不关心优先级&#xff0c;它跟我们的调度器有很大的关系&#xff0c;调度器是为了跟均衡的调度进程。 什么叫做优先级&#xff1f; 优先级和权限是两…...

2016年chatGPT之父Altman与马斯克的深度对话(值得一看)

2016年9月&#xff0c;现今OpenAI CEO&#xff0c;ChatGPT之父&#xff0c;时任创投公司Y Combinator的总裁Sam Altman在特斯拉加州弗里蒙特工厂采访了埃隆马斯克。马斯克阐述了创建OpenAI的初衷&#xff0c;以及就他而言&#xff0c;对于未来最为重要的五件事。这是OpenAI的两…...

基于vscode开发vue3项目的详细步骤教程 3 前端路由vue-router

1、Vue下载安装步骤的详细教程(亲测有效) 1_水w的博客-CSDN博客 2、Vue下载安装步骤的详细教程(亲测有效) 2 安装与创建默认项目_水w的博客-CSDN博客 3、基于vscode开发vue项目的详细步骤教程_水w的博客-CSDN博客 4、基于vscode开发vue项目的详细步骤教程 2 第三方图标库FontAw…...

【C语言】每日刷题 —— 牛客语法篇(5)

前言 大家好&#xff0c;继续更新专栏 c_牛客&#xff0c;不出意外的话每天更新十道题&#xff0c;难度也是从易到难&#xff0c;自己复习的同时也希望能帮助到大家&#xff0c;题目答案会根据我所学到的知识提供最优解。 &#x1f3e1;个人主页&#xff1a;悲伤的猪大肠9的博…...

操作系统(2.1)--进程的描述与控制

目录 一、前驱图和程序执行 1.前驱图 2.程序顺序执行 2.1 程序的顺序执行 2.2 程序顺序执行时的特征 3. 程序并发执行 3.1程序的并发执行 3.2 程序并发执行时的特征 一、前驱图和程序执行 1.前驱图 前趋图:是一个有向无循环图&#xff0c;用于描述进程之间执行的前后…...

JAVA查看动态代理类

JAVA查看代理类 1. 代理类 class 生成 System.setProperty // jdk8及之前的设置System.setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true")&#xff1b;// or System.getProperties().put("sun.misc.ProxyGenerator.saveGenerated…...

Chapter2 : SpringBoot配置

尚硅谷SpringBoot顶尖教程 1. 全局配置文件 SpringBoot使用一个全局的配置文件 application.properties 或者 application.yml &#xff0c;该配置文件放在src/main/resources目录或者类路径/config目录下面&#xff0c; 可以用来修改SpringBoot自动配置的默认值。 yml是YA…...

手撕单链表练习

Topic 1&#xff1a;LeetCode——203. 移除链表元素203. 移除链表元素 - 力扣&#xff08;LeetCode&#xff09;移除链表中的数字6操作很简单&#xff0c;我们只需要把2的指向地址修改就好了&#xff0c;原来的指向地址是6现在改为3这个思路是完全正确的&#xff0c;但是在链表…...

Kubuntu安装教程

文章目录Kubuntu介绍下载Kubuntu在VMware虚拟机中安装Kubuntu1. 点击“创建新的虚拟机”2. 选择“自定义&#xff08;高级&#xff09;”3. 按照下图所示进行设置设置网络4. 点击“自定义硬件”5. 开启虚拟机6. 进入安装界面&#xff0c;选择中文&#xff0c;之后点击“安装Kub…...

[蓝桥杯] 树状数组与线段树问题(C/C++)

文章目录 一、动态求连续区间和 1、1 题目描述 1、2 题解关键思路与解答 二、数星星 2、1 题目描述 2、2 题解关键思路与解答 三、数列区间最大值 3、1 题目描述 3、2 题解关键思路与解答 标题&#xff1a;树状数组与线段树问题 作者&#xff1a;Ggggggtm 寄语&#xff1a;与其…...

Matlab-Loma Prieta 地震分析

此示例说明如何将带时间戳的地震数据存储在时间表中以及如何使用时间表函数来分析和可视化数据。 加载地震数据 示例文件quake.mat包含 1989 年 10 月 17 日圣克鲁斯山脉 Loma Prieta 地震的 200 Hz 数据。这些数据由加州大学圣克鲁斯分校查尔斯F里希特地震实验室的 Joel Yelli…...

Spring Boot全局异常处理

使用注解方式处理全局异常使用 ControllerAdvice &#xff08;RestControllerAdvice&#xff09; 配合 ExceptionHandler适用于返回数据的请求&#xff08;一般是RESTful接口规范下的JSON报文&#xff09;package com.example.exception;import org.slf4j.Logger; import org.s…...

websocket每隔5秒给服务端send一次信息

websocket轮询每隔5秒给服务端send一次信息&#xff0c;主要功能点如下&#xff1a;socket 采用了定时器 setInterval&#xff08;&#xff09; 需要清除定时器否则会报错监听了突然关闭浏览器窗口&#xff0c;destroyed里面直接监听 window.removeEventListener("beforeu…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下&#xff1a; struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

CMake 从 GitHub 下载第三方库并使用

有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...