Trust me this channel is best for industry people.....the sad part is we do not get to see any more videos from this channel.......i would request the creator to at-least think for a membership based subscription
Hi Deepak, Your doing a excellent job of covering the most complex topic of Java threads & concurrency on your channel by providing detailed insight & explanation on each feature in simple and clear manner with hands on code. Keep it up.👍
Such great understanding, I have become a fan. How did you learnt about all these ,you prefer documentation or books or videos? Knowing the answer to this will help me hit the foundational part missing in my learning. Great video though.
You are awesome man.. i just can't explain how much you helping people to understand deep concepts in easy way. I request you to make series of RxJava ..
Hey, thanks for the awesome tutorial. I've one question, why do you even need CompletableFuture, why can we just create a TASK which handles all the sequential flow using futures and start multiple such tasks itself?
Great Job With the explanation. Though i have a question. At 15:50 when you mark enrich method to be async, how does that work in real world ? As far as i understand marking a method async means it can run on it's own without being dependent on anything else. But in this scenario it actually requires output from getOrder as input in Enrich. So does that mean it still waits until getOrder gives a output and then runs it irrespective of which thread pool it runs in ?
That's correct. The whole code is like an algorithm where each step of execution requires input from previous step and generates output for next step. Thus enrich will not even be assigned a thread until fetch order is completed. Once order task gives output, a new or same thread is assigned to enrich and that order is given as input.
DONE thanks 1:17 callable is used when you want to return a value from a thread (normal thread doesn’t return anything) Implementing call method that returns ReturnType Callable returns a Future that is a placeholder for the real value. Doing future.get() is blocking if the task is not completed 2:50 visualization We can chain methods together (instead of blocking with get() we say thenApply(...) and chain calls asynchronously See chaining from 5:59 12:50 can perform the chained asynchronous operations on the same thread or provide a different thread pool (executor service) for each operation (some operations might be cpu intensive some io, so we want to use different threadpool) 17:00 we don’t have to specify an executor to completable future, it uses forkjoinpool internally Todo continue from 1:17
Brilliant video. A lot of my confusions got resolved through this video. I will subscribe to you because I find learning with you very enriching. Please keep creating more videos like this :) Also for completablefuture if you can include collecting multiple futures through .get .all etc... It'll be complete
@15:07 creating a threadpool for every task seems like a overkill . Can we not create threadpool outside of loop it might reduce overhead of 100 threadpools
Thank you for the session. A few questions please: ONE - what if instead of creating a loop of 1:100 (i) you fetched 100 product ids, how would you revise your code to process 100 orders in parallel? TWO : what if you needed a receipt at the end of each order processing (success or failure) , how would you aggregate results of each thread without blocking and print the final 100 line status receipt from main thread?
Hello sir, I am big fan of your teaching skill. You explain tough topics in very easy way. I request you to please make some tutorials on RxJava. Thank you so much for all your effort.
Hello, thank you for the great tutorial. Did I understand right that in your example of single order processing the tasks submitted to ExecutorService are blocking to each other though each one is performed in a separate thread? if I'm correct I was wondering why did you use ExecutorService for single order processing if single order processing is sequential by its nature. And the problem is how to fire several separate order processings - not to separate different steps of the same order processing?
What to do if i have blocking operation in my task? Say IO Operation. Do i still use the CompletableFuture? if it blocks my executor thread pool then will that be acceptable?
Wonderful explanation with right example. I was always struggling to apply this pattern for my processes, this gives lot of clarity. Is it a simplified version of Saga pattern ?
Very well explained. One doubt i have, suppose if we have one executor service and we have Future.submit(task) which is performing some DB fetch or list operation and when we do future.get() with timeout overloaded method so it is blocking the thread and giving Timeout Exception. We are passing 120 sec time out limit in get() method. So how does CompletebaleFuture.suuplyAsync() and CompletableFuture.complete() will help us here?
In your case, these tasks will not be executed asynchronously since you are putting them in a single method (run()), that's why you need to create separate methods or objects for each of a task, so they can be computed in async
The below code gives the output: CompletableFuture future = CompletableFuture.supplyAsync(() -> { System.out.println(Thread.currentThread().getName()); return "Hello "; }).thenApply((i) -> { System.out.println(Thread.currentThread().getName()); return i + "World "; }); output:- ForkJoinPool.commonPool-worker-1 main Hello World while below one gives:- CompletableFuture future = CompletableFuture.supplyAsync(() -> { System.out.println(Thread.currentThread().getName()); return "Hello "; }).thenApplyAsync((i) -> { System.out.println(Thread.currentThread().getName()); return i + "World "; }); output:- ForkJoinPool.commonPool-worker-1 ForkJoinPool.commonPool-worker-1 Hello World It contradicts with your statement that supplyAsync and thenApply operations will be executed in separate threads other than main thread!
Hi, I am trying append the string with exception. Even though there is an exception.it is performing the next step(passing the previous output into next input of applyasync(()) method.(Sequence of task's) Once the exception is raised shouldn't continue. could you please tell me how to handle this. output: main pool-1-thread-2 pool-1-thread-3 java.lang.NullPointerException how are you find the below snippet. package multithreading.completablefuture; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.function.Function; public class CompletableFutureTest { public static void main(String[] args) throws InterruptedException, ExecutionException { System.out.println(Thread.currentThread().getName()); //Create New Thread pool ExecutorService newCachedThreadPool = Executors.newCachedThreadPool(); String s=null; //pass newCachedThreadPool to the completableFuture.so that completableFuture takes threads from newCachedThreadPool CompletableFuture completableFuture = CompletableFuture.supplyAsync(()->s,newCachedThreadPool) .thenApplyAsync( new Function() { @Override public String apply(String s) { System.out.println(Thread.currentThread().getName()); return s.toLowerCase(); } },newCachedThreadPool).exceptionally( e-> e.getMessage()) .thenApplyAsync( new Function() { @Override public String apply(String s) { System.out.println(Thread.currentThread().getName()); return s+" how are you"; } },newCachedThreadPool); System.out.println(completableFuture.get()); } }
Beautifully explained. Have one confusion though. Would request you to clear that. I tried below piece of code to get complete understanding. What i was expecting is all threads to complete except the one for which i purposefully slept thread for 5 seconds. for(int i=0;i"").thenAccept((o)->{ if(val==5){ try(){ Thread.sleep(5000); }catch(InterruptedException e){ } } System.out.println(o+"-printed-"+val) }) } However, i saw o/p like this which caused the confusion amit-printed-0 amit-printed-1 amit-printed-2 amit-printed-3 amit-printed-4 waited for 5 seconds and then printed.. amit-printed-5 amit-printed-6 amit-printed-7 amit-printed-8 amit-printed-9 I thought no thread will be blocked if any one cause delay. In order to fix that i had to provide a seperate threadpool like below ExecutorService executorService =Executors.newCachedThreadPool(); CompletableFuture.supplyAsync(()->"",executorService).thenAccept((o)->{... Can you please clear this confusion.
100 orders are placed inside the same thread pool. As soon as the first task, ( here: (() -> getOrder()) ) finishes, will the thread pool immediately continue work on that future object, so in essence continue with the next task from that future object, which would be (order -> enrich(order)). Or will (order -> enrich(order)) be placed at the end of the thread pool task-queue and the thread pool will first complete the task (() -> getOrder()) 100 times?
Dear Sir , I feel its just an another form of Function Functional Interface , where andThen is replaced by thenApply Above code can also be written as order.andThen(price.andThen(confirmationMessage)).apply(9);
Beautifully explained. You make everything very simple yet covering all thats relevant to the context. Please keep up the good work that benefits millions like us.
How would it be different from creating array of futures each having task of completeOrder() and this completeOrder is internally divided into multiple methods of getOrder, enrichOrder, performPayment and so on.... ?
So why cant we have a wrapper method call that in turn calls the 5 methods one by one. And then That method implements callable and returns final result. That way, each thread will be executing a different order. And we would not need CompleteableFuture . What am I missing?
Hii... I have 3 queried need to run asyn....and need to wait for the results to store in list.... Then after 3 tasks done... I need to proceed further running the remaining code.... In this scenario...could anyone suggest which is better to use... I tried executor service...but it is going sync...not waiting for the threads to complete.... Thanks in advance
I understand the dependency issues is solved compared to regular Future but don't you still need to do completablefuture.get() after your for loop? otherwise your main thread will exit while the tasks in your completable future are still running .
Beautiful explanation on this concept. I've a question here - Do we have any specific advantage if we use two thread pools instead of one? I mean to ask what are the practical scenarios to use more than one thread pool ?