当前位置:首页 > 科技  > 软件

Java 异步编程本应更简单才对

来源: 责编: 时间:2023-12-12 17:00:45 125观看
导读在过去的好多年里,多线程和异步一直作为 Java 技术里的高级部分,在技术序列中,一个语言分为入门部分、进阶部分和高级部分,所以,异步是作为其中的高级技术部分存在的。关于异步和多线程这部分吧,常常存在于面试题、八股文当

在过去的好多年里,多线程和异步一直作为 Java 技术里的高级部分,在技术序列中,一个语言分为入门部分、进阶部分和高级部分,所以,异步是作为其中的高级技术部分存在的。m7W28资讯网——每日最新资讯28at.com

关于异步和多线程这部分吧,常常存在于面试题、八股文当中,但是在大多数的项目代码中你根本看不着它。神奇吗,就是这么神奇。m7W28资讯网——每日最新资讯28at.com

纠其原因可能有两个:m7W28资讯网——每日最新资讯28at.com

  1. 本身大多数项目就很简单,根本就用不着多线程和异步,毕竟平庸属于大多数;
  2. Java 中关于多线程和异步的部分确实对于新手不太友好,涉及到的类且多且乱,而且不符合我们正常的思考方式;

我就见过很多同学,多次想入门多线程和异步,但是多次被劝退,或者在大门口反复横跳。m7W28资讯网——每日最新资讯28at.com

一旁的 Node.js 、Go 憋了一眼:哼,不就会异步吗,有那么难吗?m7W28资讯网——每日最新资讯28at.com

在 Java 中实现异步编程有什么方式呢?m7W28资讯网——每日最新资讯28at.com

异步回调函数

最开始写前端的时候最常用这种回调函数的方法,在 JavaScript 中,函数是一等公民,用法非常灵活。但是在 Java 中,回调方式并不常用。m7W28资讯网——每日最新资讯28at.com

在异步调用结束或者发生异常的时候主动的调用回调方法,以此来达到异步通知的目的。首先定义一个回调接口,如下:m7W28资讯网——每日最新资讯28at.com

public interface ICallBackService {    /**     * 回调方法     * @param args 参数     */    void callback(String ...args) throws InterruptedException;}

然后在你的异步方法中加一个回调参数,参数类型就是上面的 ICallBackService接口类型。m7W28资讯网——每日最新资讯28at.com

public class Work {    /**     * 业务逻辑     * @param callBackService     */    public void doWork(ICallBackService callBackService) throws InterruptedException {        System.out.println("开始回调");        callBackService.callback("第一个参数","第二个参数");        System.out.println("回调结束");    }}

之后在调用端调用doWork方法执行异步调用。m7W28资讯网——每日最新资讯28at.com

public static void main(String[] args) throws InterruptedException {        System.out.println("准备发起异步调用");        Thread thread = new Thread(() -> {            Work work = new Work();            try {                work.doWork(new ICallBackService() {                    @Override                    public void callback(String... args) throws InterruptedException {                        Thread.sleep(1000);                        System.out.printf("正在执行回调动作:%s%n",args==null?"无参数":String.join(",", args));                    }                });            } catch (InterruptedException e) {                throw new RuntimeException(e);            }        });        thread.start();        System.out.println("继续干其他事儿");    }

执行后,打印的结果,主线程该干什么干什么,异步方法执行后,主动调用回调方法。m7W28资讯网——每日最新资讯28at.com

准备发起异步调用 继续干其他事儿 异步执行 正在执行回调动作:第一个参数,第二个参数 回调结束m7W28资讯网——每日最新资讯28at.com

回调这种机制有个最要命的问题,它会导致代码逻辑的割裂,本来是一个从开始到结束的完整执行过程,但是回调方法脱离了代码主流程,导致我们看代码的时候产生跳跃感。m7W28资讯网——每日最新资讯28at.com

CompletableFuture 异步

自从 Java 8 出现 Future 之后,异步编程就变得简单多了,回调函数完全可以不用了。再遇到需要异步的场景时,可以直接祭出 CompletableFuture,CompletableFuture 除了有最基础的异步调用功能外,还支持异步任务链、组合任务等等。m7W28资讯网——每日最新资讯28at.com

异步编程最繁杂的地方就是流程控制,对于 NodeJS 那种天生就是异步的语言来说,有丰富的第三方框架,而对于 Java 来说,到现在都比较少。m7W28资讯网——每日最新资讯28at.com

在不借助第三方框架的情况下,CompletableFuture 应该是最优解了。m7W28资讯网——每日最新资讯28at.com

下面这段代码展示了异步调用两个任务,然后将两个任务的返回结果合并到一起,用到了 CompletableFuture 的组合任务功能。m7W28资讯网——每日最新资讯28at.com

public static void main(String[] args) throws ExecutionException, InterruptedException { //异步发起第一个任务 CompletableFuture<String> firstTask = CompletableFuture.supplyAsync(() -> {    try {     Thread.sleep(1000);    } catch (InterruptedException e) {     throw new RuntimeException(e);    }    return "第一个任务的结果";   } ); //异步发起第二个任务 CompletableFuture<String> secondTask = CompletableFuture.supplyAsync(() -> "第二个任务的结果"); // 合并两个任务的结果 CompletableFuture<String> combineTask = firstTask.thenCombineAsync(secondTask, (firstResult, secondResult) -> {  return firstResult + "&&" + secondResult; }); combineTask.thenAccept((result) -> {  System.out.println("最终结果:" + result); }); System.out.println("其他任务,该干嘛干嘛"); combineTask.join();}}

Reactor 响应式编程

用过 Spring Boot 的同学一定看到过 webFlux 这个东西,其实它就是 Reactor 中的功能。Reactor 的核心包是 reactor-core ,专为异步编程而生,已经是 Spring Boot 的内置框架了。m7W28资讯网——每日最新资讯28at.com

Reactor 是一个完全非阻塞的JVM响应式编程框架。响应式编程是一种涉及数据流和变化传播的异步编程范式。这意味着可以通过编程语言轻松地表示静态(如数组)或动态(如事件发射器)数据流。m7W28资讯网——每日最新资讯28at.com

事件发射器可以理解为事件驱动,如果做过 GUI 或客户端开发的肯定对事件驱动非常熟悉,事件驱动其实就是顺着人的思考模式来的,进行什么操作就触发什么事件。m7W28资讯网——每日最新资讯28at.com

下面是用 Reactor 实现的一个简单异步任务,其中subscribe 方法可以理解为一个事件订阅器,在里面可以订阅 onNext (也就是正常执行)、onError (发生错误是执行)以及onComplete(执行完成)等事件。每命中一个事件,就可以驱动这个事件做一些事情。m7W28资讯网——每日最新资讯28at.com

就是以顺序写代码的方式,实现异步的逻辑。m7W28资讯网——每日最新资讯28at.com

public static void main(String[] args) { Mono<String> asyncTask = Mono.fromCallable(() -> {  // 模拟异步操作  Thread.sleep(1000);  // 返回结果  return "任务执行成功"; }); // 订阅事件 asyncTask.subscribe(   result -> {    // onNext 事件,处理任务成功的情况    System.out.println("任务成功,结果:" + result);   },   error -> {    // onError 事件,处理任务出错的情况    System.err.println("任务出错:" + error.getMessage());   },   () -> {    // onComplete 事件,处理任务完成的情况    System.out.println("任务完成");   } ); // 使用 block 方法等待异步任务完成 String result = asyncTask.block(); System.out.println("主线程等待结果:" + result);}

执行以上代码前,需要引入 reactor-core 依赖包。m7W28资讯网——每日最新资讯28at.com

<dependency>  <groupId>io.projectreactor</groupId>  <artifactId>reactor-core</artifactId>  <version>3.6.0</version></dependency>

与 Reactor 类似的还有 RxJava,在 Android 开发上用的最多。m7W28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-43291-0.htmlJava 异步编程本应更简单才对

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: SpringBoot与CQRS的完美结合:构建高效、可扩展的应用程序

下一篇: 使用Linux命令行传递环境变量给Docker容器

标签:
  • 热门焦点
  • 天猫精灵Sound Pro体验:智能音箱没有音质?来听听我的

    天猫精灵Sound Pro体验:智能音箱没有音质?来听听我的

    这几年除了手机作为智能生活终端最主要的核心之外,第二个可以成为中心点的产品是什么?——是智能音箱。 手机在执行命令的时候有两种操作方式,手和智能语音助手,而智能音箱只
  • 不容错过的MSBuild技巧,必备用法详解和实践指南

    不容错过的MSBuild技巧,必备用法详解和实践指南

    一、MSBuild简介MSBuild是一种基于XML的构建引擎,用于在.NET Framework和.NET Core应用程序中自动化构建过程。它是Visual Studio的构建引擎,可在命令行或其他构建工具中使用
  • 一篇聊聊Go错误封装机制

    一篇聊聊Go错误封装机制

    %w 是用于错误包装(Error Wrapping)的格式化动词。它是用于 fmt.Errorf 和 fmt.Sprintf 函数中的一个特殊格式化动词,用于将一个错误(或其他可打印的值)包装在一个新的错误中。使
  • 让我们一起聊聊文件的操作

    让我们一起聊聊文件的操作

    文件【1】文件是什么?文件是保存数据的地方,是数据源的一种,比如大家经常使用的word文档、txt文件、excel文件、jpg文件...都是文件。文件最主要的作用就是保存数据,它既可以保
  • 如何通过Python线程池实现异步编程?

    如何通过Python线程池实现异步编程?

    线程池的概念和基本原理线程池是一种并发处理机制,它可以在程序启动时创建一组线程,并将它们置于等待任务的状态。当任务到达时,线程池中的某个线程会被唤醒并执行任务,执行完任
  • 三言两语说透柯里化和反柯里化

    三言两语说透柯里化和反柯里化

    JavaScript中的柯里化(Currying)和反柯里化(Uncurrying)是两种很有用的技术,可以帮助我们写出更加优雅、泛用的函数。本文将首先介绍柯里化和反柯里化的概念、实现原理和应用
  • 自律,给不了Keep自由!

    自律,给不了Keep自由!

    来源 | 互联网品牌官作者 | 李大为编排 | 又耳 审核 | 谷晓辉自律能不能给用户自由暂时不好说,但大概率不能给Keep自由。近日,全球最大的在线健身平台Keep正式登陆港交所,努力
  • 消费结构调整丨巨头低价博弈,拼多多还卷得动吗?

    消费结构调整丨巨头低价博弈,拼多多还卷得动吗?

    来源:征探财经作者:陈香羽随着流量红利的退潮,电商的存量博弈越来越明显。曾经主攻中高端与品质的淘宝天猫、京东重拾&ldquo;低价&rdquo;口号。而过去与他们错位竞争的拼多多,靠
  • AI芯片初创公司Tenstorrent获三星和现代1亿美元投资

    AI芯片初创公司Tenstorrent获三星和现代1亿美元投资

    Tenstorrent是一家由芯片行业资深人士Jim Keller领导的加拿大初创公司,专注于开发人工智能芯片,该公司周三表示,已经从现代汽车集团和三星投资基金等
Top