CompletableFuture、Future和RxJava'之间的差异;可见的

CompletableFuture、Future和RxJava'之间的差异;可见的,java,multithreading,asynchronous,java-8,rx-java,Java,Multithreading,Asynchronous,Java 8,Rx Java,我想知道两者之间的区别 CompletableFuture,Future和可观察的RxJava 我所知道的都是异步的,但是 Future.get()阻止线程 CompletableFuture给出了回调方法 RxJava可观察的——类似于CompletableFuture,还有其他好处(不确定) 例如:如果客户端需要进行多个服务调用,并且当我们使用Futures(Java)Future.get()将按顺序执行…想知道在RxJava中如何更好 文件上说 很难使用Futures来优化组合条件异步执行

我想知道两者之间的区别
CompletableFuture
Future
可观察的
RxJava

我所知道的都是异步的,但是

Future.get()
阻止线程

CompletableFuture
给出了回调方法

RxJava可观察的
——类似于
CompletableFuture
,还有其他好处(不确定)

例如:如果客户端需要进行多个服务调用,并且当我们使用
Futures
(Java)
Future.get()
将按顺序执行…想知道在RxJava中如何更好

文件上说

很难使用Futures来优化组合条件异步执行流(或者不可能,因为每个请求的延迟在运行时都会有所不同)。当然,这是可以做到的,但它很快就会变得复杂(因此容易出错)或者过早地阻塞Future.get(),从而消除了异步执行的好处。


非常想知道
RxJava
是如何解决这个问题的。我发现从文档中很难理解。

期货

是在Java5(2004)中引入的。它们基本上是尚未完成的操作结果的占位符。一旦操作完成,
未来
将包含该结果。例如,操作可以是提交给的或实例。操作的提交者可以使用
Future
对象检查操作是否正确,或者使用阻塞方法等待操作完成

例如:

/**
* 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
}
/**
*休眠一秒钟后返回1的任务
**/
公共静态类MyCallable实现了Callable{
@凌驾
公共整数调用()引发异常{
睡眠(1000);
返回1;
}
}
公共静态void main(字符串[]args)引发异常{
ExecutorService exec=Executors.newSingleThreadExecutor();
Future f=exec.submit(new MyCallable());
System.out.println(f.isDone());//False
System.out.println(f.get());//等待任务完成,然后打印1
}
可完成期货

在Java 8(2014)中引入。事实上,它们是常规期货的演变,灵感来自谷歌图书馆的一部分。它们是未来,也允许您将任务串成一个链。您可以使用它们来告诉某个工作线程“执行某个任务X,完成后,使用X的结果执行另一个任务”。使用CompletableFutures,您可以对操作的结果执行某些操作,而无需实际阻止线程等待结果。下面是一个简单的例子:

/**
* 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
}
/**
*一个供应商睡了一秒钟,然后返回一个
**/
公共静态类MySupplier实现供应商{
@凌驾
公共整数get(){
试一试{
睡眠(1000);
}捕捉(中断异常e){
//无所事事
}
返回1;
}
}
/**
*向给定整数加一的(纯)函数
**/
公共静态类PlusOne实现函数{
@凌驾
公共整数应用(整数x){
返回x+1;
}
}
公共静态void main(字符串[]args)引发异常{
ExecutorService exec=Executors.newSingleThreadExecutor();
CompletableFuture f=CompletableFuture.supplyAsync(新的MySupplier(),exec);
System.out.println(f.isDone());//False
CompletableFuture f2=f.thenApply(新的PlusOne());
System.out.println(f2.get());//等待“计算”完成,然后打印2
}
RxJava

是Netflix创建的整个图书馆。乍一看,它似乎类似于。是的,只是它的威力要大得多

与Futures类似,可以使用RxJava将一组同步或异步操作串在一起,以创建一个处理管道。与单一用途的Futures不同,RxJava处理零个或多个项目的流。包括无限数量的项目的永无止境的流。它也更加灵活和强大,这要感谢一个难以置信的富人

与Java8的流不同,RxJava还有一种机制,允许它处理处理处理管道的不同部分在不同线程中以不同速率运行的情况

RxJava的缺点是,尽管有可靠的文档,但由于涉及到范式转换,它仍然是一个具有挑战性的库。Rx代码也可能是调试的噩梦,特别是当涉及多个线程时,甚至更糟——如果需要背压的话

如果你想进入它,在官方网站上有各种各样的教程,加上官方的和。你也可以看一些视频,比如Rx简介,以及Rx和Futures的区别

奖励:Java 9反应流


aka是由各种库(如、和)实现的一组接口。它们允许这些反应库互连,同时保留所有重要的背压。

我从0.9开始使用Rx Java,现在是1.3.2,很快就迁移到了2.x。我在一个私人项目中使用它,我已经在那里工作了8年

如果没有这个库,我再也不会编程了。一开始我持怀疑态度,但这是你需要创造的一种完全不同的心态。一开始就很难平静下来。我有时看弹珠好几个小时。。哈哈

这只是一个实践的问题,真正了解流程(也称为观察者和观察者的契约),一旦你达到了这一点,你就会讨厌以其他方式去做

对我来说,这个图书馆并没有什么坏处

用例: 我有一个包含9个仪表(cpu、mem、网络等)的监视器视图。