2/09/2017

Comparison of Scala Future and Java 8 CompletableFuture

Colleague of mine made recently a presentation on Scala Futures. I have a good message for those constrained to Java for this or that reason.

Java since version 8 provides a mechanism similar to Scala Future.

The mechanism in Java is called CompletableFuture and here are few important differences over Future (introduces in Java 5):
  • support for promises
  • composable - possiblity of chaining multiple futures
  • possibility of registering error handling
  • all in declarative functional style

You may have already been using some concurrency utiliies library even prior to Java 8 (i.e. Guava). But you should definitelly consider CompletableFuture as a replacement over Guava or Java 5 Future.

Comparison of Scala Future and Java CompletableFuture:
Sample is taken from Rado's presentation.

Scala version

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.DurationInt
import scala.concurrent.{Await, Future}

class Futures {
  def run(a: Int, b: Int): Future[Boolean] = {
    val aFuture = callServiceA(a)
    val bFuture = callServiceB(b)
    val aStringFuture = aFuture.map(_.toString)

    for {
      aResult <- 10="" a:="" a="" aresult="" astringfuture="" b:="" b="" bfuture="" bresult="" c.length="" c:="" callservicea="" callserviceb="" callservicec="" cresult="" def="" future="" int="" nt="" oolean="" private="" string="" tring="" yield=""> 2)
}

object Futures {
  def main(args: Array[String]): Unit = {
    val future = new Futures().run(1, 2)
    val result = Await.result(future, 10.seconds)
    println(result)
  }
}

Java version using CompletableFuture

import java.util.concurrent.CompletableFuture;

public class Futures2 {

    public CompletableFuture run(int a, int b) {
        CompletableFuture aFuture = callServiceA(a);
        CompletableFuture bFuture = callServiceB(b);
        CompletableFuture aStringFuture = aFuture.thenApply(Object::toString);

        return aStringFuture.thenCombine(bFuture, (resA, resB) -> callServiceC(resA + resB)).join();
    }

    private CompletableFuture callServiceA(int a) {
        return CompletableFuture.supplyAsync(() -> a + 10);
    }

    private CompletableFuture callServiceB(int b) {
        return CompletableFuture.supplyAsync(() -> b + "10");
    }

    private CompletableFuture callServiceC(String c) {
        return CompletableFuture.supplyAsync(() -> c.length() > 2);
    }

    public static void main(String[] args) {
        CompletableFuture future = new Futures2().run(1, 2);
        Boolean result = future.join();
        System.out.println(result);
    }
}

As you can see the Java version still cannot beat the elegance of for-expression available in Scala but the basic idea of having a composable Futures is the same between Scala and Java.

My recommendation would be: If you write Java, consider using Java 8 CompletableFuture anytime you plan to write some Java Futures unless you use other concurrency utilities for historical reasons. Using original Java5 Future makes no real sense for me. Please comment if you do not agree.

0 comments :

Post a Comment