CompletableFuture, Future 및 RxJava의 Observable의 차이점


194

나는 사이의 차이를 알고 싶습니다 CompletableFuture, Future그리고 Observable RxJava.

내가 아는 것은 모두 비동기이지만

Future.get() 실을 막다

CompletableFuture 콜백 메소드를 제공합니다

RxJava Observable--- CompletableFuture다른 혜택 과 유사 (확실하지 않음)

예를 들어, 클라이언트가 여러 서비스 호출을해야하고 Futures(Java) Future.get()를 사용할 때 순차적으로 실행되는 경우 ... RxJava에서 어떻게 더 나은지 알고 싶습니다.

그리고 http://reactivex.io/intro.html 문서 는 말합니다

선물을 사용하여 조건부 비동기 실행 흐름을 최적으로 구성하는 것은 어렵습니다 (또는 각 요청의 대기 시간은 런타임에 따라 다르므로 불가능합니다). 물론이 작업을 수행 할 수는 있지만 빠르게 복잡해 지거나 오류가 발생하기 쉬워 지거나 Future.get ()에서 조기에 차단되므로 비동기 실행의 이점이 사라집니다.

RxJava이 문제를 어떻게 해결 하는지 알고 싶습니다 . 설명서에서 이해하기 어렵다는 것을 알았습니다.


각각에 대한 문서를 읽었습니까? RxJava에 익숙하지 않지만 설명서는 한 눈에 매우 철저하게 보입니다. 특히 두 선물과 비교할 수없는 것 같습니다.
FThompson

나는 겪었지만 Java 선물과 어떻게 다른지 알 수 없다 ... 내가 틀렸다면 나를 교정하라
shiv455

옵저버 블은 미래와 어떻게 비슷합니까?
FThompson

2
스레드 관리가 다른 것처럼 다른 곳을 알고 싶습니다. EX : Future.get ()은 스레드를 차단합니다 .... Observable에서 어떻게 처리 될까요 ???
shiv455

2
조금 혼란 스럽습니다 ... 높은 수준의 차이가 정말 도움이 될 것입니다 !!
shiv455

답변:


280

선물

선물 은 Java 5 (2004)에 도입되었습니다. 기본적으로 아직 완료되지 않은 작업의 결과에 대한 자리 표시 자입니다. 작업이 완료되면에 Future해당 결과가 포함됩니다. 예를 들어 작업은 ExecutorService에 제출 된 Runnable 또는 Callable 인스턴스 일 수 있습니다 . 오퍼레이션 제출자는 오브젝트를 사용하여 오퍼레이션이 isDone () 인지 여부를 확인 하거나 블로킹 get () 메소드를 사용하여 완료 될 때까지 기다릴 있습니다.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
}

CompletableFutures

CompletableFutures 는 Java 8 (2014)에 도입되었습니다. 그것들은 사실 구아바 도서관의 일부인 구글의 리스너 러블 퓨처스 ( Google의 Listenable Futures) 에서 영감을 얻은 정기 선물의 진화입니다 . 그것들은 또한 당신이 체인으로 작업을 묶을 수있는 선물입니다. 그것들을 사용하여 일부 작업자 스레드에게 "일부 작업 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
}

RxJava

RxJava 는 Netflix에서 작성된 반응 형 프로그래밍을 위한 전체 라이브러리입니다 . 한 눈에 보면 Java 8의 스트림 과 비슷한 것으로 보입니다 . 그것은 훨씬 더 강력하다는 것을 제외하고는입니다.

선물과 마찬가지로 RxJava를 사용하여 여러 개의 동기식 또는 비동기식 작업을 함께 처리하여 처리 파이프 라인을 만들 수 있습니다. 일회용 인 Futures와 달리 RxJava 는 0 개 이상의 항목 스트림 에서 작동 합니다. 무한한 수의 항목으로 끝나지 않는 스트림 포함. 믿을 수 없을만큼 풍부한 연산자 세트 덕분에 훨씬 유연하고 강력 합니다.

Java 8의 스트림과 달리 RxJava에는 역압 메커니즘이있어 처리 파이프 라인의 다른 부분이 다른 스레드 에서 다른 속도로 작동하는 경우를 처리 할 수 있습니다 .

RxJava의 단점은 탄탄한 문서에도 불구하고 관련된 패러다임 전환으로 인해 배우기 어려운 라이브러리라는 것입니다. Rx 코드는 특히 여러 스레드가 관련되어 있고 더 심한 경우 역압이 필요한 경우 디버깅하기에 악몽이 될 수 있습니다.

그것에 들어가고 싶다면 공식 웹 사이트와 공식 문서Javadoc 에 대한 다양한 자습서 의 전체 페이지 가 있습니다. Rx에 대한 간략한 소개를 제공하고 Rx와 미래의 차이점에 대해 이야기하는 비디오와 같은 일부 비디오를 살펴볼 수도 있습니다 .

보너스 : Java 9 반응성 스트림

Java 9의 Reactive Streams 일명 Flow APIRxJava 2 , Akka StreamsVertx 와 같은 다양한 반응성 스트림 라이브러리로 구현되는 인터페이스 세트입니다 . 이것들은 모든 반응성 배압을 유지하면서 이러한 반응성 라이브러리가 상호 연결되도록합니다.


Rx가이 작업을 수행하는 방법에 대한 예제 코드를 제공하면 좋을 것입니다.
Zinan Xing

따라서 Reactive Streams를 사용하면 하나의 응용 프로그램에서 RxJava, Akka 및 Vertx를 혼합 할 수 있습니까?
IgorGanapolsky

1
@IgorGanapolsky 네.
Malt

CompletableFutures에서는 콜백 메소드를 사용하는데,이 콜백 메소드는 한 메소드의 출력이 다른 콜백의 입력 인 경우에도 차단합니다. Future.get () 호출로 미래 블록으로. CompletableFutures가 차단하지 않고 Future.get ()이 호출을 차단한다고하는 이유는 무엇입니까? 설명하십시오
Deepak

1
트윗 담아 가기 각각 Future은 아직 완료되었거나 완료되지 않은 단일 결과에 대한 자리 표시 자입니다 . 동일한 작업을 다시 수행하면 새 Future인스턴스가 생성됩니다. RxJava 는 언제든지 올 수있는 결과 스트림 을 처리합니다. 따라서 일련의 작업은 단일 결과를 얻을 수있는 단일 RxJava 옵저버 블을 반환 할 수 있습니다. 우편물을 계속 펌핑하는 단일 우편 봉투와 공압 ​​튜브의 차이점과 비슷합니다.
Malt

21

0.9부터 Rx Java를 사용하여 현재 1.3.2에서 곧 2.x로 마이그레이션하고 있으며 이미 8 년 동안 작업 한 개인 프로젝트에서이를 사용합니다.

이 라이브러리 없이는 더 이상 프로그래밍하지 않을 것입니다. 처음에는 회의적 이었지만, 당신이 만들어야 할 완전히 다른 상태입니다. 처음에는 조용히 어렵다. 나는 때때로 몇 시간 동안 구슬을보고 있었다 .. lol

그것은 단지 연습의 문제이며 실제로 흐름 (일명 관찰자와 계약자 계약)을 알게되면, 일단 거기에 도착하면 그렇지 않으면 싫어합니다.

저에게 그 도서관에는 실제로 단점이 없습니다.

유스 케이스 : 9 게이지 (cpu, mem, network 등)가 포함 된 모니터보기가 있습니다. 뷰를 시작할 때 뷰는 9 미터에 대한 모든 데이터를 포함하는 관찰 가능 (간격)을 리턴하는 시스템 모니터 클래스를 구독합니다. 매 초마다 새로운 결과를 뷰에 푸시합니다 (따라서 폴링하지 않습니다 !!!). 이 Observable은 플랫 맵을 사용하여 9 개의 다른 소스에서 동시에 데이터를 가져오고 결과를 onNext ()에서 얻을 수있는 새 모델로 압축합니다.

도대체 선물, 컴 포터블 등으로 어떻게 할 건가요? 행운을 빌어 요! :)

Rx Java는 저를위한 프로그래밍의 많은 문제를 해결하고 훨씬 쉬운 방법으로 만듭니다 ...

장점 :

  • Statelss !!! (가장 중요한 것, 가장 중요한 것)
  • 즉시 사용 가능한 스레드 관리
  • 자체 수명주기가있는 시퀀스 구축
  • 모든 것이 관찰 가능하므로 체인 연결이 쉽습니다.
  • 적은 코드 작성
  • 클래스 패스의 단일 병 (매우 가벼운)
  • 매우 동시
  • 더 이상 콜백 지옥 없음
  • 가입자 기반 (소비자와 생산자 간의 긴밀한 계약)
  • 배압 전략 (회로 차단기 등)
  • 화려한 오류 처리 및 복구
  • 아주 좋은 문서 (대리석 <3)
  • 완벽한 제어
  • 더 많은 ...

단점 :-테스트하기 어렵다


13
~ " 이 라이브러리 없이는 더 이상 프로그래밍하지 않을 것입니다. " "RxJava는 모든 소프트웨어 프로젝트에있어 가장 중요한 것입니까?
IgorGanapolsky

비동기 이벤트 스트림이 없어도 유용합니까?
Mukesh Verma
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.