我想知道两者之间的区别
CompletableFuture,Future和可观察的RxJava
我所知道的都是异步的,但是
Future.get()阻止线程
CompletableFuture给出了回调方法
RxJava可观察的——类似于CompletableFuture,还有其他好处(不确定)
例如:如果客户端需要进行多个服务调用,并且当我们使用Futures(Java)Future.get()将按顺序执行…想知道在RxJava中如何更好
以及文件http://reactivex.io/intro.html 说
很难使用Futures来优化组合条件异步执行流(或者不可能,因为每个请求的延迟在运行时都会有所不同)。当然,这是可以做到的,但它很快就会变得复杂(因此容易出错)或者过早地阻塞Future.get(),从而消除了异步执行的好处。
非常想知道RxJava是如何解决这个问题的。我发现从文档中很难理解
期货
Java 5(2004)引入了期货。它们基本上是尚未完成的操作结果的占位符。一旦操作完成,未来将包含该结果。例如,操作可以是提交给ExecutorService的可运行或可调用实例。操作的提交者可以使用Future对象检查操作是否为isDone(),或者使用blocking get()方法等待操作完成
例如:
/**
*休眠一秒钟后返回1的任务
**/
公共静态类MyCallable实现了Callable<;整数>;{
@凌驾
公共整数调用()引发异常{
睡眠(1000);
返回1;
}
}
公共静态void main(字符串[]args)引发异常{
ExecutorService exec=Executors.newSingleThreadExecutor();
Future<;Integer>;f=exec.submit(new MyCallable());
System.out.println(f.isDone());//False
System.out.println(f.get());//等待任务完成,然后打印1
}
可完成期货
Java 8(2014)引入了CompletableFutures。事实上,它们是常规期货的演变,灵感来自谷歌的Listenable Futures,它是Guava图书馆的一部分。它们是未来,也允许您将任务串成一个链。您可以使用它们来告诉某个工作线程“执行某个任务X,完成后,使用X的结果执行另一个任务”。使用CompletableFutures,您可以对操作的结果执行某些操作,而无需实际阻止线程等待结果。下面是一个简单的例子:
/**
*一个供应商睡了一秒钟,然后返回一个
**/
公共静态类MySupplier实现供应商<;整数>;{
@凌驾
公共整数get(){
试一试{
睡眠(1000);
}捕捉(中断异常e){
//无所事事
}
返回1;
}
}
/**
*向给定整数加一的(纯)函数
**/
公共静态类PlusOne实现函数<;整数,整数>;{
@凌驾
公共整数应用(整数x){
返回x+1;
}
}
公共静态void main(字符串[]args)引发异常{
ExecutorService exec=Executors.newSingleThreadExecutor();
CompletableFuture<;Integer>;f=CompletableFuture.supplyAsync(新的MySupplier(),exec);
System.out.println(f.isDone());//False
CompletableFuture<;Integer>;f2=f.thenApply(新PlusOne());
System.out.println(f2.get());//等待“计算”完成,然后打印2
}
RxJava
RxJava是Netflix创建的整个反应式编程库。乍一看,它似乎类似于Java8的流。是的,只是它的威力要大得多
与Futures类似,可以使用RxJava将一组同步或异步操作串在一起,以创建一个处理管道。与单一用途的期货不同,RxJava处理零或多个项目的流。包括无限数量的项目的永无止境的流。它也更加灵活和强大,这要归功于一组难以置信的丰富运营商
与Java8的流不同,RxJava还有一个背压机制,允许它处理处理处理管道的不同部分在不同线程中以不同速率运行的情况
RxJava的缺点是,尽管有可靠的文档,但由于涉及到范式转换,它仍然是一个具有挑战性的库。Rx代码也可能是调试的噩梦,特别是当涉及多个线程时,甚至更糟——如果需要背压的话
如果你想了解它,官方网站上有一整页的各种教程,外加官方文档和Javadoc。你也可以看一些视频,比如这段视频,它简要介绍了Rx,还讨论了Rx和Futures之间的区别
奖励:Java 9反应流
Java 9的反应流又名Flow API是由各种反应流库(如RxJava 2、Akka Streams和Vertx)实现的一组接口。它们允许这些反应库互连,同时保留所有重要的背压