·      Non-blocking

·      Ability to Programmatically completing a future

·      Perform Error handling

·      Ability to Chain several futures

·      Ability to combine results of multiple futures (that run in parallel)

 

 

CompletableFuture : A Simplified Guide to Async Programming | by Rahat Shaikh | The Startup | Medium

// Get Movies playing for the selected showtime (date and time)

 

CompletableFuture<List<Movie>> getMovieList(String day){
        return  CompletableFuture.supplyAsync( ()-> {
            List movieList = new ArrayList<Movie>();
            //getMovieList from backend
           
return movieList;
    });
}

 

// Select seats for the movie
//ShowDetails includes movie selected, date and time of the movie, along with seats selected for that show

 

CompletableFuture<ShowDetails> selectSeats (ShowTime showTime) {
      return CompletableFuture.supplyAsync(() -> {    
        ShowDetails showDetails = new ShowDetails();
        showDetails.setSeats(selectSeatsForShow());
        return showDetails;
    });
 }

 

//Customer selects a movie from the movie list


CompletableFuture<Movie> selectMovie(List<Movie> movies){
    //user selects movie
   
return CompletableFuture.supplyAsync(() -> {
        movie = getCustomerSelectedMovie();
        return movie;
      });
    }

 

//Calculate ticket price


CompletableFuture<TicketPrice> getTicketPrice (ShowDetails showdetails){
      return CompletableFuture.supplyAsync(() -> {
          ticketPrice = getTotalTicketPrice();
          return ticketPrice; //final price
      });
}

 

// Apply promo code if available


ShowDetails applyPromoCode (ShowDetails showdetails, String promoCode){
    showdetails.setFinalDiscount(getDiscount(promoCode));
    return showdetails;
}

 

Chaining multiple futures to book the Movie Show

public void bookMyShow(ShowDetails showDetails, String promoCode){
             CompletableFuture result = getMovieList(showDetails.getShowTime().getDay())
            .thenCompose(movies -> selectMovie(movies))
            .thenCompose(movie ->  selectSeats(showDetails.getShowTime())
            .thenApply(showDetails1 -> applyPromoCode(showDetails1,promoCode))
            .thenCompose(showDetails2 -> getTicketPrice(showDetails2)));
}


Asynchronous programming in Java with CompletableFuture (linkedin.com)


No alt text provided for this image

 

No alt text provided for this image

 

No alt text provided for this image

 

No alt text provided for this image

 

 

The difference has to do with the Executor that is responsible for running the code. Each operator on CompletableFuture generally has 3 versions.

1.     thenApply(fn) - runs fn on a thread defined by the CompleteableFuture on which it is called,

so you generally cannot know where this will be executed.

It might immediately execute if the result is already available.

2.     thenApplyAsync(fn) - runs fn on a environment-defined executor regardless of circumstances. For CompletableFuture this will generally be ForkJoinPool.commonPool().

3.     thenApplyAsync(fn,exec) - runs fn on exec.

 

In the end the result is the same, but the scheduling behavior depends on the choice of method.