我想知道它们之间的区别
CompletableFuture
,Future
和Observable
RxJava
。
我所知道的都是异步但
Future.get()
阻止线程
CompletableFuture
给出了回调方法
RxJava Observable
---与CompletableFuture
相似,但有其他好处(不确定)
例如:如果客户端需要进行多次服务调用,并且当我们使用Futures
时(Java)Future.get()
将按顺序执行...想知道它在RxJava中的效果如何.. < / p>
文档http://reactivex.io/intro.html说
很难使用Futures来最佳地组合条件异步执行流程(或者不可能,因为每个请求的延迟在运行时会有所不同)。当然,这可以完成,但它很快变得复杂(因此容易出错)或者过早地阻塞Future.get(),这消除了异步执行的好处。
真的很想知道RxJava
如何解决这个问题。我发现从文档中很难理解。
答案 0 :(得分:224)
<强>期货强>
Java 5(2004)中引入了 Futures。对于尚未发生的结果,他们基本上是占位符。他们承诺一旦操作完成,就会保留一些操作的结果。该操作可以是提交给Runnable的Callable或ExecutorService实例。操作的提交者可以使用Future
对象来检查操作isDone(),或者等待它使用get()完成。
示例:
/**
* A task that sleeps for a second, then returns 1
**/
public static class MyCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
Thread.sleep(1000);
return 1;
}
}
public static void main(String[] args) throws Exception{
ExecutorService exec = Executors.newSingleThreadExecutor();
Future<Integer> f = exec.submit(new MyCallable());
System.out.println(f.isDone()); //False
System.out.println(f.get()); //Waits until the task is done, then prints 1
}
<强> CompletableFutures 强>
Java 8(2014)中引入了CompletableFutures。它们实际上是常规期货的演变,受到Listenable Futures库Guava的一部分的RxJava的启发。它们是Futures,它还允许您将任务串联起来。您可以使用它们来告诉某些工作线程去做一些任务X,当您完成后,使用X&#34;的结果去做其他事情。这是一个简单的例子:
/**
* A supplier that sleeps for a second, and then returns one
**/
public static class MySupplier implements Supplier<Integer> {
@Override
public Integer get() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
//Do nothing
}
return 1;
}
}
/**
* A (pure) function that adds one to a given Integer
**/
public static class PlusOne implements Function<Integer, Integer> {
@Override
public Integer apply(Integer x) {
return x + 1;
}
}
public static void main(String[] args) throws Exception {
ExecutorService exec = Executors.newSingleThreadExecutor();
CompletableFuture<Integer> f = CompletableFuture.supplyAsync(new MySupplier(), exec);
System.out.println(f.isDone()); // False
CompletableFuture<Integer> f2 = f.thenApply(new PlusOne());
System.out.println(f2.get()); // Waits until the "calculation" is done, then prints 2
}
<强> RxJava 强>
reactive programming是在Netflix上创建的Java 8's streams的完整库。一目了然,它似乎与set of operators相似。它是,除了它更强大。
与Futures类似,RxJava可用于将一堆同步或异步操作串联在一起以创建处理管道。与一次性使用的Futures不同,RxJava适用于零个或多个项目的 streams 。包括具有无限数量项目的永无止境的流。由于令人难以置信的丰富backpressure,它也变得更加灵活和强大。
与Java 8的流不同,RxJava还具有page机制,允许它处理处理管道的不同部分在不同线程中运行的情况,以不同的速率
RxJava的缺点是,尽管文档扎实,但由于涉及范式的转变,它是一个具有挑战性的库。 Rx代码也可能是调试的噩梦,特别是如果涉及多个线程,更糟糕的是 - 如果需要背压。
如果你想进入它,在官方网站上加上官方documentation和Javadoc的各种教程this one。您还可以查看一些视频,例如Java 9's Reactive Streams,其中简要介绍了Rx,并讨论了Rx和期货之间的差异。
奖励:Java 9 Reactive Streams
Flow API又名reactive streams是由RxJava 2,Akka Streams和Vertx等各种{{3}}库实施的一组接口。它们允许这些反应库互连,同时保留所有重要的背压。
答案 1 :(得分:15)
我从0.9开始使用Rx Java,现在是1.3.2,很快就会迁移到2.x我在一个已经工作了8年的私人项目中使用它。
我根本不会在没有这个库的情况下编程。一开始我很怀疑,但这是你需要创造的另一种完整的心态。一开始很安静。我有时会看着弹珠几个小时..大声笑
这只是一个实践问题而且真正了解流程(也就是可观察者和观察者的合同),一旦你到达那里,你就会讨厌这样做。
对我而言,该图书馆并没有真正的缺点。
用例: 我有一个监视器视图,包含9个仪表(CPU,内存,网络等...)。启动视图时,视图会将自身订阅到系统监视器类,该类返回包含9米所有数据的可观察(间隔)。 它将每秒推送一个新结果到视图(所以不要轮询!!!)。 该observable使用flatmap同时(异步!)从9个不同的源获取数据,并将结果压缩到您的视图将在onNext()上获得的新模型。
你将如何用期货,补充等来做到这一点......祝你好运! :)
Rx Java为我解决了编程中的许多问题,并且使用起来更容易......
优点:
缺点: - 难以测试
答案 2 :(得分:3)
CompletableFuture相对于常规Future的主要优势在于,CompletableFuture利用了极其强大的流API并为您提供了回调处理程序来链接任务,如果您使用常规Future则绝对没有。通过提供异步体系结构,CompletableFuture成为处理计算繁重的map-reduce任务的方式,而不必担心应用程序的性能。
答案 3 :(得分:1)
所有三个接口用于将价值从生产者转移到消费者。消费者可以分为两种:
通信接口在其他方面也有所不同:
结果:
Future
使用同步接口传输单个值
CompletableFuture
使用同步和异步接口传输单个值
Rx
使用带有背压的异步接口传输多个值
此外,所有这些通信工具都支持传输异常。这并非总是如此。例如,BlockingQueue
不会。
答案 4 :(得分:1)
Java 的 Future
是一个占位符,用于保存将来会通过阻塞 API 完成的内容。您必须使用它的 isDone()
方法定期轮询它以检查该任务是否已完成。当然,您可以实现自己的异步代码来管理轮询逻辑。但是,它会产生更多样板代码和调试开销。
Java 的 CompletableFuture
由 Scala 的 Future 创新。它带有一个内部回调方法。一旦完成,将触发回调方法并告诉线程应该执行下游操作。这就是为什么它有 thenApply
方法对包裹在 CompletableFuture
中的对象进行进一步操作。
RxJava 的 Observable
是 CompletableFuture
的增强版本。它允许您处理背压。在我们上面提到的 thenApply
方法(甚至还有它的兄弟 thenApplyAsync
)中,可能会发生这种情况:下游方法想要调用有时可能不可用的外部服务。在这种情况下,CompleteableFuture
将完全失败,您必须自己处理错误。但是,Observable
允许您处理背压并在外部服务可用后继续执行。
另外还有一个类似Observable
的接口:Flowable
。它们是为不同的目的而设计的。通常 Flowable
专用于处理冷和非定时操作,而 Observable
专用于处理需要即时响应的执行。在此处查看官方文档:https://github.com/ReactiveX/RxJava#backpressure