当前位置: 首页 > 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…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...

视觉slam十四讲实践部分记录——ch2、ch3

ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...

接口自动化测试:HttpRunner基础

相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具&#xff0c;支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议&#xff0c;涵盖接口测试、性能测试、数字体验监测等测试类型…...

OD 算法题 B卷【正整数到Excel编号之间的转换】

文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的&#xff1a;a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...

Axure 下拉框联动

实现选省、选完省之后选对应省份下的市区...

JDK 17 序列化是怎么回事

如何序列化&#xff1f;其实很简单&#xff0c;就是根据每个类型&#xff0c;用工厂类调用。逐个完成。 没什么漂亮的代码&#xff0c;只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...

算法—栈系列

一&#xff1a;删除字符串中的所有相邻重复项 class Solution { public:string removeDuplicates(string s) {stack<char> st;for(int i 0; i < s.size(); i){char target s[i];if(!st.empty() && target st.top())st.pop();elsest.push(s[i]);}string ret…...