异步响应式编程可以极大的提高系统的并发呑吐量,但由于Java没有类似于其他语言的Async/Await机制,所以只能通过CompletableFuture.thenXXX()来串联各个异步任务,这给习惯了写同步增删改查的小伙伴们带来了些小麻烦。如果说C#基于状态机在编译时实现了await转换,那么Java肯定也可以基于相同的原理实现await,作者上网一搜果然找到了ea-async,使用与C#相同的方式实现了await异步方法,这回终于可以愉快的撸Java异步代码了。

一、 示例代码

  举个扣减库存并保存订单的例子,在没有await方式下的示例代码如下:

public CompletableFuture<?> saveOrder(Order order) {
//1.开始事务
return DataStore.DemoDB.beginTransaction().thenCompose(txn -> {
//2.扣库存
var cmd = new SqlUpdateCommand<Order>();
cmd.update(e -> e.Stock = e.Stock - order.Quantity); //当前量扣除订单量
cmd.where(e -> e.ProductId == order.ProductId);
var outs = cmd.output(e -> e.Stock);
return cmd.execAsync(txn).thenCompose(rows -> {
//3.判断库存
if (rows == 0 || outs.get(0) < 0)
return CompletableFuture.failedFuture("库存不足");
//4.保存订单
return order.saveAsync(txn);
}).thenCompose(r -> txn.commitAsync()); //5.递交事务
}).thenApply(r -> "Done.");
}

  WTF! 一层套一层的回调,这还只是个简单的例子啊。但是如果使用await的方式,业务逻辑就变得清爽多了:

import static sys.Async.await;

public CompletableFuture<?> saveOrder(Order order) {
//1.开始事务
var txn = await(DataStore.DemoDB.beginTransaction());
//2.扣库存
var cmd = new SqlUpdateCommand<Order>();
cmd.update(e -> e.Stock = e.Stock - order.Quantity); //当前量扣除订单量
cmd.where(e -> e.ProductId == order.ProductId);
var outs = cmd.output(e -> e.Stock);
var rows = await(cmd.execAsync(txn));
//3.判断库存
if (rows == 0 || outs.get(0) < 0)
return CompletableFuture.failedFuture("库存不足");
//4.保存订单
await(order.saveAsync(txn));
//5.递交事务
await(txn.commitAsync());
return CompletableFuture.completedFuture("Done.");
}

二、 实现原理

  核心思想没有变,还是代码分析转换。作者原本想利用JDT在源码层进行await转换,但是工作量还是比较大的,在这里感谢github/ea-async项目,使得作者只修改了十几行代码就实现了上述效果,具体转换过程如下:

  1. 服务模型的虚拟代码经过JDT分析、转换、编译为class文件(参考前篇说明);
  2. 调用ea-async的Transformer类直接分析与转换class文件内的await方法调用,生成新的class文件。

具体参考源码PublishService的compileService()及transformAsync()方法。

三、 本篇小结

  先解释一下上篇"优雅的Java ORM"小伙伴们的评论,有说这么多ORM干吗还要造一个的,也有说不够"优雅"的,其实造轮子最根本的原因是:异步支持!,Spring WebFlux及VertX有相应的异步操作数据库的支持,但本框架没法集成。MyBatis之类的全是同步操作,小的应用系统没有问题,高并发系统的呑吐量就非常可怜了,这个大家可以测一下Spring MVC与WebFlux的性能对比。

  软件技术日新月异,新一代的开发框架必定是异步的!对于作者来讲Spring还不够简单优雅,运行的也不够快,所以才会尝试重新造这个大轮子,争取让应用系统的开发人员有更多的时间关注数据结构、业务逻辑和用户体验,也争取让小伙伴们有一个丝般顺滑的开发体验。

边码代码边码文实属不易,作者需要您的支持请您多多点赞推荐!另欢迎感兴趣的小伙伴加入我们!

终于可以愉快的撸Java异步代码了!的更多相关文章

  1. Android--在Android应用中愉快地写C/C++代码(转)

    1 前言 一直想在android层面写c进程,然后java可以与c进程交互,以前在android源码中想玩就可以直接在init.rc中加上交叉编译好的c进程就可以了,而在ide中,也就是ndk编译后各 ...

  2. FastDFS搭建及java整合代码【转】

    FastDFS软件介绍 1.什么是FastDFS FastDFS是用C语言编写的一款开源的分布式文件系统.FastDFS为互联网量身定制,充分考虑了冗余备份.负载均衡.线性扩容等机制,并注重高可用.高 ...

  3. Java 异步处理简单实践

    Java 异步处理简单实践 http://www.cnblogs.com/fangfan/p/4047932.html 同步与异步 通常同步意味着一个任务的某个处理过程会对多个线程在用串行化处理,而异 ...

  4. Paip.Php Java 异步编程。推模型与拉模型。响应式(Reactive)”编程FutureData总结... 1

    Paip.Php  Java 异步编程.推模型与拉模型.响应式(Reactive)"编程FutureData总结... 1.1.1       异步调用的实现以及角色(:调用者 提货单) F ...

  5. java异步编程降低延迟

    目录 java异步编程降低延迟 一.ExecutorService和CompletionService 二.CompletableFuture(重要) 三.stream中的parallel(并行流) ...

  6. java 异步机制与同步机制的区别

    所谓异步输入输出机制,是指在进行输入输出处理时,不必等到输入输出处理完毕才返回.所以异步的同义语是非阻塞(None Blocking). 网上有很多网友用很通俗的比喻  把同步和异步讲解的很透彻 转过 ...

  7. OS信号实现Java异步通知

    OS信号实现Java异步通知本文将结合操作系统的信号机制,来尝试实现一个简单的,不依赖功能环境的Java异步通知功能.没有特殊说明,本文所有的示例,都是基于Linux.信号简介信号是在软件层次上对中断 ...

  8. Java 异步编程

    昨天头儿给的学习文档我还没看完,头儿说:“MongoDB光会简单的添删改查什么的不行,要深入了解,你们连$set和$inc使用场景都分不清.” 确实,学习过一年多SQL,确实对学习MongoDB有点影 ...

  9. 如何编写优雅的异步代码 — CompletableFuture

    前言 在我们的意识里,同步执行的程序都比较符合人们的思维方式,而异步的东西通常都不好处理.在异步计算的情况下,以回调表示的动作往往会分散在代码中,也可能相互嵌套在内部,如果需要处理其中一个步骤中可能发 ...

随机推荐

  1. 3款pdf插件介绍

    1.pdf.js:推荐使用.小窗口可以使用iframe来解决.ie8及以下不支持,但是360的兼容模式ie8下可以在新标签页中打开,在iframe中打不开,ie8中在新标签页也不支持打开.可使用ua- ...

  2. Springboot mini - Solon详解(五)- Solon扩展机制之Solon Plugin

    Springboot min -Solon 详解系列文章: Springboot mini - Solon详解(一)- 快速入门 Springboot mini - Solon详解(二)- Solon ...

  3. C++异常之二 基本语法

    2. 异常处理的基本语法 下面是一个基本的代码例子,说明 throw.try.catch的基本用法,与 catch 的类型自动匹配: 1 #include <iostream> 2 #in ...

  4. 珍藏的C语言编程系列教程

    本文有332个文字,大小约为2KB,预计阅读时间1分钟 这是本人珍藏的C语言.C++系列教程. 相信每个Coder的第一门编程语言就是C语言吧, 现在也依然很热门,不谈了.直接上链接,感兴趣的直接存, ...

  5. Spring中毒太深,离开Spring我居然连最基本的接口都不会写了

    前言 随着 Spring 的崛起以及其功能的完善,现在可能绝大部分项目的开发都是使用 Spring(全家桶) 来进行开发,Spring也确实和其名字一样,是开发者的春天,Spring 解放了程序员的双 ...

  6. JS怎么把for循环出来的东西放到一个数组里

    var students=[ {name: "vehicleTravelLicenseCopyBack", id: "a1"}, {name: "ve ...

  7. VSCode---REST Client接口测试辅助工具

    我们一般都会用 PostMan 来完成接口测试的工作,因为用起来十分简单快捷,但是一直以来我也在寻找更好的方案,一个不用切换窗口多开一个 app 的方案 -- 终于在使用 VSCode 一段时版本间, ...

  8. Python基础入门:注释、变量、运算符与数据类型

    一.为什么要学习python? python的特点 python作为一门脚本语言,在越来越多的行业和领域发挥着重大作用,比如机器学习.网站开发.数据分析.爬虫.自动化测试. 同时,python具备以下 ...

  9. [UWP] - 修改应用程序在任务栏上的显示Logo

    用VS2015在windows 10上开发一个UWP的应用,由于windows 10对store应用进行了窗口化,因此可以看到在任务栏上看到应用程序的图标,但是看起来会感觉应用Logo会被嵌在另一个容 ...

  10. Windows7里面怎么实现FTP服务功能

    1.安装FTP服务 点击:计算机 -->属性 --> 控制面板主页 --> 程序 --> 打开或关闭Windows功能 2. 调出管理工具 操作: 鼠标点击工具栏,选择属性,选 ...