CompletableFuture, Future ve RxJava'nın Gözlemlenebilir Farkı


194

Ben arasındaki farkı bilmek istiyorum CompletableFuture, Futureve Observable RxJava.

Bildiğim tek şey eşzamansız ama

Future.get() ipliği engeller

CompletableFuture geri arama yöntemlerini verir

RxJava Observable--- CompletableFuturediğer faydalara benzer (emin değilim)

Örneğin: istemcinin birden çok servis çağrısı yapması gerekiyorsa ve Futures(Java) kullandığımızda Future.get()sıralı olarak yürütülürse ... RxJava'da nasıl daha iyi olduğunu bilmek ister ..

Ve http://reactivex.io/intro.html belgeleri diyor ki

Koşullu eşzamansız yürütme akışlarını en uygun şekilde oluşturmak için Futures kullanmak zordur (veya her isteğin gecikmesi çalışma zamanında değiştiğinden imkansızdır). Bu elbette yapılabilir, ancak hızla karmaşıklaşır (ve dolayısıyla hataya eğilimli) veya zaman uyumsuz yürütmenin faydasını ortadan kaldıran Future.get () 'i erken engeller.

RxJavaBu sorunu nasıl çözdüğünü bilmek gerçekten ilgilendi . Belgelerden anlamayı zor buldum.


Her birinin belgelerini okudunuz mu? RxJava'yı tamamen bilmiyorum, ancak belgeler bir bakışta son derece ayrıntılı görünüyor. İki gelecekle özellikle karşılaştırılabilir görünmüyor.
FThompson

Ben geçtim ama Java futures gelen ne kadar farklı elde edemedi ... im yanlış eğer beni düzelt
düzelt shiv455

Gözlenebilirler geleceğe nasıl benziyor?
FThompson

2
iplik yönetiminde farklı olduğu gibi nerede farklı olduğunu bilmek ister misiniz? EX: Future.get () iş parçacığını engeller .... Gözlemlenebilir nasıl ele alınacak ???
shiv455

2
en azından benim için biraz kafa karıştırıcı ... yüksek seviye farkı gerçekten yararlı olurdu!
shiv455

Yanıtlar:


281

Vadeli

Futures , Java 5'de (2004) tanıtıldı. Bunlar henüz tamamlanmamış bir operasyonun sonucu olarak yer tutucular. İşlem bittikten sonra Futureirade bu sonucu içerecektir. Örneğin, bir işlem ExecutorService'e gönderilen Runnable veya Callable örneği olabilir . İşlemin göndericisi nesneyi işlemin Bitti () olup olmadığını kontrol etmek için kullanabilir veya engelleme get () yöntemini kullanarak tamamlanmasını bekleyebilir .Future

Misal:

/**
* 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'de (2014) tanıtıldı. Bunlar aslında Google'ın esinlenerek düzenli Vadeli bir evrim vardır Listenable Futures parçası Guava kütüphanesinin bir . Bunlar aynı zamanda bir zincirde görevleri bir araya getirmenize izin veren Futures'lardır. Bunları, bir işçi iş parçacığına "gidip X görevini yapın ve işiniz bittiğinde X'in sonucunu kullanarak başka bir şey yapın" demesini söylemek için kullanabilirsiniz. CompletableFutures kullanarak, sonucu beklemek için bir iş parçacığını gerçekten engellemeden işlemin sonucuyla ilgili bir şeyler yapabilirsiniz. İşte basit bir örnek:

/**
* 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 reaktif programlama için bütün bir kütüphanedir Netflix'te oluşturulan . Bir bakışta, Java 8'in akışlarına benzer görünecek . Çok daha güçlü olması dışında.

Futures'a benzer şekilde, RxJava, bir işleme hattı oluşturmak için bir grup senkronize veya senkronize olmayan eylemi bir araya getirmek için kullanılabilir. Tek kullanımlık Futures'tan farklı olarak, RxJava sıfır veya daha fazla öğenin akışı üzerinde çalışır . Sonsuz sayıda öğe içeren bitmeyen akışlar dahil. İnanılmaz derecede zengin olması sayesinde çok daha esnek ve güçlü operatörler .

Java 8'in akışları farklı olarak, RxJava de vardır backpressure , işleme boru hattınızın farklı bölümlerinin farklı iş parçacıklarında farklı hızlarda çalıştığı durumları işlemesine izin veren mekanizmasına .

RxJava'nın dezavantajı, sağlam belgelere rağmen, ilgili paradigma kayması nedeniyle öğrenmenin zor bir kütüphane olmasıdır. Rx kodu, özellikle birden fazla iş parçacığı varsa ve daha da kötüsü - geri basınç gerekiyorsa, hata ayıklamak için bir kabus olabilir.

Buna girmek istiyorsanız, resmi web sitesinde çeşitli eğitimlerin yanı sıra resmi belgeler ve Javadoc'un bir sayfası var . Ayrıca , Rx'e kısa bir giriş yapan ve ayrıca Rx ve Futures arasındaki farkları anlatan bu gibi videolara da göz atabilirsiniz .

Bonus: Java 9 Reaktif Akışları

Java 9'un Reaktif Akışları aka Flow API'si RxJava 2 , Akka Akışları ve Vertx gibi çeşitli reaktif akış kütüphaneleri tarafından uygulanan bir Arabirimler kümesidir . Tüm önemli geri basıncı korurken, bu reaktif kütüphanelerin birbirine bağlanmasına izin verirler.


Rx bunu nasıl yaptığına dair örnek kod vermek güzel olurdu
Zinan Xing

Reaktif Akışları kullanarak RxJava, Akka ve Vertx'i tek bir uygulamada karıştırabilir miyiz?
IgorGanapolsky

1
@IgorGanapolsky Evet.
Malt

CompletableFutures'da geri çağrı yöntemlerini kullandığımızda, bu geri çağrı yöntemleri bir yöntemin çıktısı diğer geri çağrı girdiyse de engellenir. Future.get () çağrısı ile gelecekteki blok olarak. CompletableFutures engellenmezken neden Future.get () yönteminin çağrıyı engellediği söyleniyor. Lütfen açıklayın
Deepak

1
@Federico Sure. Her biri Future, henüz tamamlanmış veya tamamlanmamış tek bir sonuç için yer tutucudur . Aynı işlemi tekrar yaparsanız, yeni bir Futureörnek alırsınız . RxJava , herhangi bir zamanda gelebilecek sonuç akışlarıyla ilgilenir . Bu nedenle bir dizi işlem, bir grup sonucu dışarı pompalayacak tek bir RxJava gözlemlenebilir döndürebilir. Bu, tek bir posta zarfı ve postayı pompalamaya devam eden pnömatik bir tüp arasındaki farka benziyor.
Malt

21

Rx Java ile 0.9'dan beri, şimdi 1.3.2'de çalışıyorum ve yakında 2.x'e geçiyorum. Bunu 8 yıldır çalıştığım özel bir projede kullanıyorum.

Artık bu kütüphane olmadan programlama yapmam. Başlangıçta şüpheciydim ama yaratmanız gereken başka bir zihin durumu. Başlangıçta oldukça zor. Bazen mermere saatlerce bakıyordum .. lol

Bu sadece bir uygulama meselesidir ve akışı (gözlemlenebilir ve gözlemci olarak da bilinir) gerçekten tanımaktır, oraya vardığınızda, bunu yapmaktan nefret edersiniz.

Benim için bu kütüphane üzerinde gerçekten bir dezavantaj yok.

Kullanım örneği: 9 gösterge içeren bir monitör görünümüm var (cpu, mem, ağ, vb ...). Görünümü başlatırken, görünüm kendisini 9 metre için tüm verileri içeren gözlemlenebilir (aralık) döndüren bir sistem monitörü sınıfına abone olur. Her saniyeyi görünüme yeni bir sonuç itecektir (bu yüzden yoklama !!!). Bu gözlemlenebilir, 9 farklı kaynaktan veri almak için eşzamanlı olarak (async!) Bir flatmap kullanır ve sonucu onNext () üzerinde alacağınız yeni bir modele sıkıştırır.

Futures, completables vs ile bunu nasıl yapacaksın ... İyi şanslar! :)

Rx Java benim için programlamada birçok sorunu çözüyor ve bir şekilde çok daha kolay hale getiriyor ...

Avantajları:

  • Statelss !!! (söylenecek önemli şey, belki de en önemlisi)
  • İş parçacığı yönetimi kullanıma hazır
  • Kendi yaşam döngüsüne sahip diziler oluşturun
  • Her şey gözlemlenebilir olduğundan zincirleme kolaydır
  • Yazmak için daha az kod
  • Sınıf yolunda tek kavanoz (çok hafif)
  • Yüksek eşzamanlı
  • Artık geri arama yok
  • Abone tabanlı (tüketici ve üretici arasında sıkı sözleşme)
  • Karşı basınç stratejileri (devre kesici benzeri)
  • Mükemmel hata işleme ve kurtarma
  • Çok güzel belgeler (mermerler <3)
  • Tam denetim
  • Çok daha fazlası ...

Dezavantajları: - Test edilmesi zor


13
~ " Artık bu kütüphane olmadan program yapmazdım. " Yani RxJava, tüm yazılım projelerinin hepsinin sonu mu?
IgorGanapolsky

Akış Eşzamansız etkinliklerim olmasa bile yararlı olur mu?
Mukesh Verma
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.