Hello, dissidents.
Today, we are going to have a really interesting and useful lesson, we are going to learn how to work
with compatible future.
This is something what personally I use very often when I work with MultiThreaded and in my opinion,
this class and its features underestimated and on engineers.
So today I'm going to show you how powerful this type is and when we might use it.
We are going to learn how to execute tasks with comfortable future during the lesson will learn the
concept of the callback and how to work with callbacks with the help of compatible future.
Besides that, today we are going to learn more advanced concepts.
Namely, I'm going to show you how we can combine future objects together and work with them.
And at the end of the lesson, we learn how to manage exceptions in complete the future.
Let's start learning this topic with the help of official documentation and the source code.
Let's understand first what complete the future is and what problem it solves.
Creating multi spending programs is not an easy thing, especially it's hard to manage asynchronous
computations and build dependencies between those.
In case you have multiple steps in a program and each step may depend on execution of the previous step,
you try to find out ways how to implement this and code it may end up with having multiple callbacks
and logic may be scattered across the application.
And what about handlin errors that happened on one of the steps?
Should we handle the same error in different places?
Or we can find a way to create an exception handler for multiple connected steps during Lutece writing
processes.
Committable Future helps us to solve this issue.
And even more compatible future was released in Java Version eight to improve future interface.
Future Interface was released in Java Version five.
It was a great improvement, but its introduction doesn't solve an issue of connecting multiple tasks
between each other and API for error handling, along with future interface composable.
Future also implements another interface that was introduced in Java version eight.
It is called Completion Stage.
This time defines the context for behavior.
For an asynchronous computation step is that we combine with other steps in the source code of this
type and we find a lot of different methods.
Most of them are overloaded.
So implementation of completion, stage and future interfaces in complete the future gives us around
50 masses available to use those methods primarily for composing, combining, executing asynchronous
tasks and error handling.
Let's start watching compatible future code examples.
I create a separate package for examples only was complete the future.
I share the length of the package with you in attachments to this in the name No.
One, I'm going to show you the simplest and probably one of the most popular usage of compressible
future.
It is super easy to run asynchronous tasks with this type.
It has multiple static masses that allow us to execute task in a separate thread without long configuration
of a solid object or creation of executive service and shutting down it later in the case.
I just want to execute asynchronous task.
I just could run a static method of compostable feature class.
That's it.
For example, you just need to notify another service about work being started or done and you don't
care about response from the client.
Such a similar case cases may happen sometimes when you call around asking for joint command post is
used.
This approach is good for intensive and fast tasks, considering the fact when Java process is finished,
there is no common pool.
I put sleep here to let this thread be executed and bring this tax to consult run.
I think massive is overloaded.
There is a massive that takes Runnable object and executor as a method of argument.
In the next example here, I put the same lambda function for Runnable and Executive Service, considering
the fact that the second example here use a separate executive service and doesn't use for common pool,
I don't need to put any sleep here.
I'm not afraid.
Java process termination.
And you can see in console, thread, name and console output that imitates Sambrook that may be done
in a separate track by the thread name.
You can understand that surrounds is executed with the help of Fajon pull.
Make sure you watched my lesson about, for example, if you want them more about.
In the second case we use Red Bull executer.
That's why Swed name is different.
That's it.
We're getting this example.
Let's move on.
The next example is related was one of the features of computable future type you can complete task
was method.
To be honest, I have never used this method besides learning and educational purposes.
But this message is like one of the main sinks, incompatible future when you potentially need to use
it, let's say you need to fetch some data from another server.
Does this operation would take some time?
That's why you decided to run this task in a separate thread.
But something happened and the remote server doesn't respond for a specific amount of time.
And you really need to proceed with execution.
In this case, you may complete the future by returning the default value.
Let's look at the example I want to put into console result of a asynchronous calculation.
I call calculate calculator sink as it returns any future object.
And considering the fact that it's completed all the future implements future interface.
I can return composable future when needed.
I create an instance of complete double future.
After that I create cash, streetball and submit callable for execution.
I imitate a call to external server.
Imagine that I want to get some price double values that I will assign to the result variable and will
return it by making my sleep.
I imitate the delay in request a server.
After that I shut down executive service and I call a termination.
I am waiting for two seconds, only having the reference to the future object.
I can verify whether all calculations are done or not done.
If calculations are done, I return the reference to the future object.
If calculations are not done, I call complete Masset on my accomplishable future object and they pass
some default price values that I'm happy to return.
In this case, future won't be done and we are going to have force here because we await termination
only for two seconds.
But we expect tasks to be completed in five seconds after call and complete Masset completed.
All future will be considered as completed and I return the reference to the compatible future.
When I get the reference to the future, I just called Get MassArt and I extract complete result.
Let's run this program and you can see that in console we have nine point ninety nine.
This is our default price and we don't get new value.
Is it clear if no, ask question below this video and I will be happy to answer.
If everything is clear for you, then let's proceed.
The next example is located in the file was named Elmasry.
This time I'm going to show your supply.
I think similar to the run, I think said we can submit a task without boilerplate code.
But the only difference is that in releasing we passed Runnable object and here we need to pass supplier.
In case you're not familiar with supplier type, feel free to watch my course about functional programming
for Java engineers.
In that course, we have plenty of examples that will help you to understand a lot of functional interfaces,
including supply.
Basically, that's it.
Supply returns the value.
That's why I can get future after Colen supply, async and extract result from it.
Let's run this program and print result the console.
And as you can see in console, I managed to extract text from the future object and printed it to console.
So feel free to use this method in case you have something to execute in a separate thread and you need
to get the result of the execution hub that this example is clear.
Let's move on now.
We'll create with you a sequence of steps that should be executed one after another in a separate thread,
because it might happen that you need to perform another action based on the previous step completion.
So basically you can act complete about future, which should automatically get called once the future
completes.
Z is also often called a callback.
It is also known as call after function.
We have three methods that allow us to do this, then apply, then accept.
Xinran, we're going to review examples with these methods.
Now, let's start from then apply method in the file demo for I create super simple example to help
easily understand how this works.
The pardon is the same so you can apply it to any other tasks and calculations.
Imagine that you want to fetch user iji by email from one API and once you have user ID, you can request
total number of purchases for this user from another API and you need the result of first task execution
to get a D in order to be able to execute the second request I call supply asking to submit my first
task.
Is this a supplier that produces some result and after that I call then apply method and pass a function
that takes result of previous task execution as an input argument and that returns as a value.
I have console output in first and in second task just to imitate.
As a result of then applying, Masset is a future object that you can use to retrieve a result of computation
of the last step, you can build multiple steps like this, Michael, and then apply and to use in the
result of execution from previous step as an input argument for the next step.
Is that clear?
If yes, then great.
Also, there is another similar method then apply.
I think.
What would be the difference between then apply and then apply?
I think basically the main difference is the executor as it is used to execute these tasks by default,
then apply method uses the same threat that was used by the first task and uses the same exact as it
was defined by computable future on which it is called.
Then apply, I think uses independent executor by default.
It is forgery and common pool, but there is an overloaded method that allows it to pass executor service
like in the similar example below that will bring us to the same result.
I use executive service and then apply.
I think Massett in general, if you have multiple tasks for execution, I would just recommend it to
have executive service configured and use it for tasks execution that's triggered and then apply.
Masset, let's move on.
I open them a file file.
So as you already understood, then apply method returns to some future object.
But in case you don't want to create a return statement to return the result of the execution after
the final step and you just need to have some code got executed, you have to use it and accept us run.
We we're going to talk in a minute.
What is the difference between these two?
Let me just start explaining of that.
Except first, in this case, imagine that we need to extract full and complete user profile and in
the first step of this process, received text representation of user profile.
And after that, I just call then accept method to perform some operations that doesn't require me to
return the result.
For example, just saving this information somewhere in the application, probably in the user session
object or in local database, it doesn't matter, for example, then accept also returns compatible
future.
But this is compatible future that this parametrized by void type.
In case you would try to extract value from this future, you would get no, let's run this program.
And as you can see in console, I prefer that the console now so we can say that extract value from
the future after Colon's and accept doesn't make a lot of sense.
Similar to the previous example then, except MassArt has methods that allow to use separate executer
for each step, then accept async Macit use a separate executer for tasks execution.
Is it clear?
Now let's look at the next example with Iran Masset and understand how it is different.
I open domestiques, almost similar example, but in this case I just want to see user profile to another
server.
And once this task will be executed, I want to look that user profile has been saved, but perform
any other actions after the first one.
In this case, there is no need for me to call supply async because the result of computation of the
first step will not be passed to anywhere.
That's why it wouldn't matter at all what value will be returned from the first step of the execution.
And after it I just called and run method to perform some actions in this case just to notify the user.
Profile has been saved and I can proceed with other operations that were dependent on the first one.
And again, we are future objects rechanneled, but it contains nothing in response.
And also we have similar Massata then run, which is called Zinda Run.
I think this method will use separate executive service either for example or the ones at the specified
hope that you understand now how to work with these matters.
Let's continue.
I'd like to talk about a combination of different future objects.
I open them.
A seven file imagines that you already have two masses and both of them return complete the future object.
The first method extracts user details by ID and the second method extracts credit rating by user details.
You already know how to use and apply MassArt.
Let's look how it would look like in this case when you would call one method and after that you would
call another method that also the Transcom political future you would get as a result compatible future.
That is parametrized by compatible future.
It is not too convenient to work with the result.
Now you should call get method twice to extract the results that you wanted, especially for such cases.
There is a composed method in case I call them compose.
Instead of apply, I get complete.
Future parametrized by the time of my results.
And that's it.
This solution is more elegant in case you want to compose one future object out of two.
If in those three Mapai in Java, I am sure you remember that there is such as flat map, that mass,
it is similar to this one.
So you can extract completely a future from another conceivable future and get flat representation of
the result.
Also in this case, we have one task running after another.
So two dependent tasks.
We have also similar methods that are called then compose a scene.
I believe you already understand.
What is the difference then?
Compose a scene you separate.
Executer let me open them are eight now in the case, two tasks are independent and you just want to
complete two of them in any order you can call them combine.
In this case you can perform some actions after two tasks are completed.
So again, we have to masset that return complete double future.
One method returns weight and another method which is height.
Each massive sleep for one second inside.
This is just to imitate some operation time in the main mass that we get weight in KG future, and after
that we call them combined Masset and we pass height in centimeters future.
That together with my function, as you remember, my function can take two arguments and returns.
The result, these two arguments would be the result of these two future objects.
And once we get the result, we apply the function inside the BI function.
I want to calculate the body mass index by following a specific formula here.
Let's run the program and you can see in concert that after and weight and height I start calculating
body mass index.
And the main thing here is that I don't need to have connection between execution of the first and the
second task that can be executed in parallel.
But I just need the result of both computations.
And for the convention, we have then combined async method, which is overloaded and has a version
that was default executer and was a separate executer argument.
I open them online file and you already know that.
Then combined, MassArt returns the result of computation of the future objects.
We have another method that is called Xanax, Sambo's, that instead of by function takes by consumer,
that means it doesn't return any value and just consumes the results of execution of two tasks and works
with two future objects and return nothing.
So in this case, you can see that I supply lambda expressions.
It returns first.
I call accept the both and after that I supply lambda expressions.
It returns the second and we just bring concatenated string to consult.
And in case I would extract the value from the future object, I would get no because then accept the
most massive returns.
Computable future parametrized by voit type.
Lets run the program and you can see that I printed concatenated string the new value proofs that my
future contains.
Nassan also we have similar MassArt foreign conventions.
We have then accept both async method.
So far I've learned math that allowed us to combine only to complete the future objects.
Now we are going to land mass that allow us to combine multiple completive of future objects.
There are two masses of and any of both of these masses accept variable arguments of political future
type.
Let's review these two.
I open them more than we have here.
Simple, but a very interesting example.
We are going to come up with a few more masses that I didn't share with you before.
The goal of this example is to create a list of strings and turn them into a capital case.
Pretty simple scenario.
And we will solve this task with computable future, not because I love complicated things, but just
to help you understand this example, I create a list of strings.
After that, I create a string from this list I call Map Masset and passing functions that completed
the future method returns and you complete the future object as it is already completed with the given
value.
After that, I then apply Masset for each string and invoke the late uppercase Delate uppercase sleep
for a random amount of time, but up to one second and returns the current string in uppercase.
This random sleep imitates operation time in case there will be more actions here.
After that, we have a list of future objects I call all of Masset and POS array of future objects,
considering the fact that all of Masad may accept.
The verbal argument, all of matter will reach a new political future that is completed when all of
the give and complete futures complete.
But what would happen in case one of the given futures complete, exceptionally Zenzi complete political
future also does so as a result, if any of the given political futures are not reflected in the return
to complete the future, but may be obtained by inspecting them individually.
After that, I call one complete MassArt.
This message returns and you completion stage with the same result of exception as the stage and executes
that given action.
When this stage completes one complete takes by consumer as method argument in this by consumer receives
the result on now if none and the exception on now if none of the stages arguments to get the results,
we need to go over our features one more time.
In this case, I just print each updated string to console pay attention that I could get now masset
of complete double future.
We didn't discuss this method yet.
Get now returns the value if computation is finished and returns default values that we pass as a method
argument if result is not ready.
In our case we use one complete Macit.
So we assume that all of the features were done by this moment in our program.
So I print all uppercase string to consult.
Let me run this program.
That's it.
Any questions regarding all of Masset leaves them under review in case of any the next them is related
to any of method.
Let me open them on file here.
We have absolutely similar example, but with only one difference.
Instead of all of I call any of method here any of Masset returns and you completed all future that
is completed when any of the given completed will future complete.
So in this case, the first future that will be completed will be printed to cancel.
Let me run this program that it I have been processed first and that's it.
Nothing else is printed to consult.
Does it make sense?
Great.
Let's proceed.
And the last, but not least for today, I am going to show you how to handle exceptions with the help
of compatible future.
This type allows us to handle errors in a chain of asynchronous computation steps.
Instead of having to try catch block, we have handle Masset that receives two arguments.
The first one is a result of computation in case all processing was finished successfully, and the
second argument is exceptions thrown in case there was some exceptional case.
I open them Otwell file in this file we have examples of error handling I supply.
I think the next task I have int variables that is equal to five and I divided by zero.
We're going to have error if we take exception in this line.
But take into account this is a onetime exception.
Compiler doesn't warn us about potential Hanlan, but I'm smart enough to handle Masad after the last
step.
And by the way, you may have multiple steps handle.
Masset will catch exception on any step of execution in case there are no exceptions.
Result of execution would be in the first argument and in case a recent exception, I have the reference
to the exception object passed as a second argument that surrounds this program.
And in console output we can see that we enter this.
If LOC I printed the class of the exception, it is completion exception and it is caused by arithmetic
exception.
So we can see how a completion exception is the regional exception.
We have also another method for error.
Hanlan.
It is called exceptionally.
The difference is that it takes not by function like handle matter, but it takes function and has parameter
of Straubel type is the same way I check exception here and considering the fact that I don't have any
result available, I can return some default value, for example.
That's it.
We learned a lot about the future.
In case there is anything else you want to know about compatible future, please ask questions.
Now let's recap what we have learned in this lesson, in this lesson we learned complete about future.
As I said in the beginning of the lesson, it is very useful class that I use very often when I work
with multithreaded, it helps to solve a lot of pain points.
We learned different methods that describes how to execute tasks was complete the future also.
Now you know what a callback is and how to work with callbacks.
With the help of compatible future thought, we managed to build multiple.
Step with this writing process and real examples, you saw how we can combine future objects and work
with them, and at the end of the lesson, I explained how we can manage exceptions with complete double
future time.
That's all for this lesson.
Thanks a lot for your attention.
Have a great day and see you in the next lesson.