Tuesday, 18 January 2022

Future vs CompletableFutures

 Futures

Futures were introduced in Java 5 (2004). They're basically placeholders for a result of an operation that hasn't finished yet. Once the operation finishes, the Future will contain that result. For example, an operation can be a Runnable or Callable instance that is submitted to an ExecutorService. The submitter of the operation can use the Future object to check whether the operation isDone(), or wait for it to finish using the blocking get() method.

Example:

/**
* 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 were introduced in Java 8 (2014). They are in fact an evolution of regular Futures, inspired by Google's Listenable Futures, part of the Guava library. They are Futures that also allow you to string tasks together in a chain. You can use them to tell some worker thread to "go do some task X, and when you're done, go do this other thing using the result of X". Using CompletableFutures, you can do something with the result of the operation without actually blocking a thread to wait for the result. Here's a simple example:

/**
* 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
}

Java 11 features

 Few important features captured:

 1) Java 11 is commercialized 

2) Run the java code without compile. It's internally compiles. We no need to compile.

3) Add few String related methods:

1) isBlank ("".isBlank() and  " ".isBlank() ==> returns true)
2)strip(),stripLeading(), stripTrailing() : removes the blank spaces in the string
3)repeat(int) --> "str".repeat(2); ==> outputstrstr

4) Introduced var (Local Variable Type Inference), can't be used in Class level/method parameter level/method return type (for more info : https://www.youtube.com/watch?v=qRuGoUy5fUI)

example: var list = new ArrayList<String>();

5) Java 11 standardizes the Http CLient API. The new API supports both HTTP/1.1 and HTTP/2

6) Java 11 strives to make reading and writing of String convenient.

readString()
writeString()

Example:

Path path = Files.writeString(Files.createTempFile("test", ".txt"), "This is my own text");
System.out.println(path);
String s = Files.readString(path);
System.out.println(s); //output : This is my own text

7) Introduced ChaCha20 and Poly1305 Cryptographic Algorithms. These algorithms will be implemented in the SunJCE provider.

8) Epsilon Garbage collector has been added. It is used for testing performance and memory stress testing. It could also be used for short lived jobs.

9) Supports TLS 1.3 and all other backwards compatibility TLS versions.

10) Collections.toArray(Type) ==> converts the collection to array of Objects.

public class ToArrayEx {
    public static void main(String[] args) {
        List<String> strings = Arrays.asList("ku", "ra", "ga");
        String[] stringArray = strings.toArray(String[]::new);
        System.out.println(stringArray.length);
    }
}

11) Z Garbage collection (experimental, not formalized yet) - It's a low latency garbage collector, can handle Terabytes of heap size.