[译]20个使用 Java CompletableFuture的例子

在Java中异步编程,不一定非要使用rxJava, Java本身的库中的CompletableFuture可以很好的应对大部分的场景。

原文: 20 Examples of Using Java’s CompletableFuture, 作者 Mahmoud Anouti。

这篇文章介绍 Java 8 的 CompletionStage API和它的标准库的实现 CompletableFuture。API通过例子的方式演示了它的行为,每个例子演示一到两个行为。

既然CompletableFuture类实现了CompletionStage接口,首先我们需要理解这个接口的契约。它代表了一个特定的计算的阶段,可以同步或者异步的被完成。你可以把它看成一个计算流水线上的一个单元,最终会产生一个最终结果,这意味着几个CompletionStage可以串联起来,一个完成的阶段可以触发下一阶段的执行,接着触发下一次,接着……

除了实现CompletionStage接口, CompletableFuture也实现了future接口, 代表一个未完成的异步事件。CompletableFuture提供了方法,能够显式地完成这个future,所以它叫CompletableFuture

阅读全文

[转][译]在 Java 中运用动态挂载实现 Bug 的热修复

原文: Fixing Bugs in Running Java Code with Dynamic Attach by Rafael Winterhalter

开源中国组织翻译: 在 Java 中运用动态挂载实现 Bug 的热修复 by TedCruz、
无若、LeoXu、Tocy等。

大多数 JVM 具备 Java 的 HotSwap 特性,大部分开发者认为它仅仅是一个调试工具。利用这一特性,有可能在不重启 Java 进程条件下,改变 Java 方法的实现。典型的例子是使用 IDE 来编码。然而 HotSwap 可以在生产环境中实现这一功能。通过这种方式,不用停止运行程序,就可以扩展在线的应用程序,或者在运行的项目上修复小的错误。这篇文章中,我将演示动态绑定、应用运行期代码变化进行绑定、介绍一些工具 API 以及 Byte Buddy 库,这个库提供了一些 API 代码改变更方便。

阅读全文

[转]Spring 5 新功能:函数式 Web 框架

英文原文:New in Spring 5: Functional Web Framework by
中文翻译: Spring 5 新功能:函数式 Web 框架 by 开源中国

就像在昨天Juergen发布的博客的一样,Spring 5.0框架第二个里程碑版本中介绍了一个新的函数式web框架。在这篇文章中,我将更详细的介绍这个框架。

紧记该函数式web框架是在Spring5.0第一个里程碑版本基础上构建的。并且我们依旧提供基于注解的请求处理(例如@Controller,@RequestMapping),关于基于注解的请求处理部分的相关信息请查阅关于Spring5.0第一个里程碑版本的博客。

阅读全文

[译]Java火焰图

在我的前一天转的一篇文章中([转]go's march to low latency gc),Twitch的Rhys Hiltner使用火焰图(FlameGraph)来分析Go程序的性能给我留下了深刻的印象,它使用Brendan Gregg创建的火焰图工具生成直观的图像,很方便的分析Go的各个方法占用的CPU的时间。

因为我的一部分时间还是使用Java开发,所以就想到有没有Java相关的工具生成火焰图呢?答案当然是肯定的,而且它更早的应用于Java程序的性能分析。

火焰图工具的作者Brendan Gregg专门写了一篇文章:Java Flame Graphs,介绍如何生成火焰图的。这就是本文要翻译的文章。

Netflix深度使用了火焰图工具,他们专门写了一篇文章Java in Flames,介绍他们是如何使用的,而且前段时间他们又写了一篇文章: 如何使用火焰图分析性能,每天为Netflix节省一千三百万分钟的计算时间,文中介绍了他们如何使用火焰题找到耗时的问题所在,为公司节省了大量的时间和金钱。(Brendan Gregg就是Netflix的员工,他的站点觉得是一个值得阅读的地方,还有很多其它性能相关的专题,比如Linux性能工具 http://www.brendangregg.com/linuxperf.html)

既然火焰图这么有效,你难道不想了解一下吗?

以下是Brendan Gregg文章的翻译。

阅读全文

继续了解Java的纤程库 - Quasar

前一篇文章Java中的纤程库 - Quasar中我做了简单的介绍,现在进一步介绍这个纤程库。

Quasar还没有得到广泛的应用,搜寻整个github也就pinterest/quasar-thrift这么一个像样的使用Quasar的库,。并且官方的文档也很简陋,很多地方并没有详细的介绍,和Maven的集成也不是很好。这些都限制了Quasar的进一步发展。

但是,作为目前最好用的Java coroutine的实现,它在某些情况下的性能还是表现相当出色的,希望这个项目能够得到更大的支持和快速发展。

因为Quasar文档的缺乏,所以使用起来需要不断的摸索和在论坛上搜索答案,本文将一些记录了我在Quasar使用过程中的一些探索。

阅读全文

[转]列出所有的Maven依赖

转发一个脚本,以列表形式显示maven中的依赖。
原文: List all your Maven dependencies

1
2
3
4
5
6
7
8
9
10
# first grab all dependencies
mvn dependency:resolve
# then list them with -o to keep noise low,
# remove extra information and duplicates
mvn -o dependency:list \
| grep ":.*:.*:.*" \
| cut -d] -f2- \
| sed 's/:[a-z]*$//g' \
| sort -u

输出结果如下所示:

1
2
3
4
5
6
7
asm:asm:jar:1.5.3
asm:asm:jar:3.1
biz.aQute:bnd:jar:0.0.169
cglib:cglib:jar:2.1_3
classworlds:classworlds:jar:1.1
classworlds:classworlds:jar:1.1-alpha-2
...

理解RxJava的线程模型

ReactiveX是Reactive Extensions的缩写,一般简写为Rx,最初是LINQ的一个扩展,由微软的架构师Erik Meijer领导的团队开发,在2012年11月开源,Rx是一个编程模型,目标是提供一致的编程接口,帮助开发者更方便的处理异步数据流,Rx库支持.NET、JavaScript和C++,Rx近几年越来越流行了,现在已经支持几乎全部的流行编程语言了,Rx的大部分语言库由ReactiveX这个组织负责维护,比较流行的有RxJava/RxJS/Rx.NET,社区网站是 reactivex.io

Netflix参考微软的Reactive Extensions创建了Java的实现RxJava,主要是为了简化服务器端的并发。2013年二月份,Ben Christensen 和 Jafar Husain发在Netflix技术博客的一篇文章第一次向世界展示了RxJava。

RxJava也在Android开发中得到广泛的应用。

ReactiveX
An API for asynchronous programming with observable streams.
A combination of the best ideas from the Observer pattern, the Iterator pattern, and functional programming.

虽然RxJava是为异步编程实现的库,但是如果不清楚它的使用,或者错误地使用了它的线程调度,反而不能很好的利用它的异步编程提到系统的处理速度。本文通过实例演示错误的RxJava的使用,解释RxJava的线程调度模型,主要介绍SchedulerobserveOnsubscribeOn的使用。

阅读全文

Java中的纤程库 - Quasar

最近遇到的一个问题大概是微服务架构中经常会遇到的一个问题:

服务 A 是我们开发的系统,它的业务需要调用 BCD 等多个服务,这些服务是通过http的访问提供的。 问题是 BCD 这些服务都是第三方提供的,不能保证它们的响应时间,快的话十几毫秒,慢的话甚至1秒多,所以这些服务的Latency比较长。幸运地是这些服务都是集群部署的,容错率和并发支持都比较高,所以不担心它们的并发性能,唯一不爽的就是就是它们的Latency太高了。

简化的微服务架构

系统A会从Client接收Request, 每个Request的处理都需要多次调用B、C、D的服务,所以完成一个Request可能需要1到2秒的时间。为了让A能更好地支持并发数,系统中使用线程池处理这些Request。当然这是一个非常简化的模型,实际的业务处理比较复杂。

可以预见,因为系统B、C、D的延迟,导致整个业务处理都很慢,即使使用线程池,但是每个线程还是会阻塞在B、C、D的调用上,导致I/O阻塞了这些线程, CPU利用率相对来说不是那么高。

当然在测试的时候使用的是B、C、D的模拟器,没有预想到它们的响应是那么慢,因此测试数据的结果还不错,吞吐率还可以,但是在实际环境中问题就暴露出来了。

阅读全文

[转]Java 8:StampedLock,ReadWriteLock以及synchronized的比较

原文出处:Tal Weiss, 译文出处: 有孚

同步区域有点像拜访你的公公婆婆。你当然是希望待的时间越短越好。说到锁的话情况也是一样的,你希望获取锁以及进入临界区域的时间越短越好,这样才不会造成瓶颈。

synchronized关键字是语言层面的加锁机制,它可以用于方法以及代码块。这个关键字是由HotSpot JVM来实现的。我们在代码中分配的每一个对象,比如String, Array或者一个JSON文档,在GC的层面的对象头部,都内建了一个加锁的机制。JIT编译器也是类似的,它在进行字节码的编译和反编译的时候,都取决于特定的某个锁的具体的状态和竞争级别。

同步块的一个问题在于——进入临界区域内的线程不能超过一个。这对生产者消费者场景是一个很大的打击,尽管这里有些线程会尝试进行独占式的数据编辑,而另外一些线程只是希望读取一下数据,这个是可以和别的线程同时进行的。

读写锁(ReadWriteLock)是一个理想的解决方案。你可以指定哪些线程会阻塞别的操作(写线程),哪些线程可以和别人共同进行内容的消费(读线程)。一个美满的结局?恐怕不是。

读写锁不像同步块,它并不是JVM中内建支持的,它只不过是段普通的代码。同样的,要想实现锁机制,它得引导CPU原子地或者按某个特定的顺序来执行某些特定的操作,以避免竞争条件。这通常都是通过JVM预留的一个后门来实现的——unsafe类。读写锁使用的是CAS操作来将值直接设置到内存中去,这是它们线程排队算法中的一部分。

尽管这样,读写锁也还不够快,有时候甚至会表现得非常慢,慢到你压根儿就不应该使用它。然而JDK的这帮家伙们没有放弃治疗,现在他们带来了一个全新的StampedLock。这个读写锁使用了一组新的算法以及Java 8 JDK中引入的内存屏障的特性,这使得这个锁更高效也更健壮。

它兑现了自己的诺言了吗?让我们拭目以待。

阅读全文