| 1 |
| 00:00:05,000 --> 00:00:06,000 |
| Hello, dissidents. |
|
|
| 2 |
| 00:00:06,000 --> 00:00:11,000 |
| Today, we are going to have a really interesting and useful lesson, we are going to learn how to work |
|
|
| 3 |
| 00:00:11,000 --> 00:00:12,000 |
| with compatible future. |
|
|
| 4 |
| 00:00:13,000 --> 00:00:18,000 |
| This is something what personally I use very often when I work with MultiThreaded and in my opinion, |
|
|
| 5 |
| 00:00:18,000 --> 00:00:22,000 |
| this class and its features underestimated and on engineers. |
|
|
| 6 |
| 00:00:22,000 --> 00:00:28,000 |
| So today I'm going to show you how powerful this type is and when we might use it. |
|
|
| 7 |
| 00:00:28,000 --> 00:00:33,000 |
| We are going to learn how to execute tasks with comfortable future during the lesson will learn the |
|
|
| 8 |
| 00:00:33,000 --> 00:00:39,000 |
| concept of the callback and how to work with callbacks with the help of compatible future. |
|
|
| 9 |
| 00:00:39,000 --> 00:00:43,000 |
| Besides that, today we are going to learn more advanced concepts. |
|
|
| 10 |
| 00:00:44,000 --> 00:00:49,000 |
| Namely, I'm going to show you how we can combine future objects together and work with them. |
|
|
| 11 |
| 00:00:50,000 --> 00:00:55,000 |
| And at the end of the lesson, we learn how to manage exceptions in complete the future. |
|
|
| 12 |
| 00:00:55,000 --> 00:01:00,000 |
| Let's start learning this topic with the help of official documentation and the source code. |
|
|
| 13 |
| 00:01:00,000 --> 00:01:05,000 |
| Let's understand first what complete the future is and what problem it solves. |
|
|
| 14 |
| 00:01:05,000 --> 00:01:11,000 |
| Creating multi spending programs is not an easy thing, especially it's hard to manage asynchronous |
|
|
| 15 |
| 00:01:11,000 --> 00:01:14,000 |
| computations and build dependencies between those. |
|
|
| 16 |
| 00:01:15,000 --> 00:01:21,000 |
| In case you have multiple steps in a program and each step may depend on execution of the previous step, |
|
|
| 17 |
| 00:01:21,000 --> 00:01:27,000 |
| you try to find out ways how to implement this and code it may end up with having multiple callbacks |
|
|
| 18 |
| 00:01:28,000 --> 00:01:30,000 |
| and logic may be scattered across the application. |
|
|
| 19 |
| 00:01:31,000 --> 00:01:34,000 |
| And what about handlin errors that happened on one of the steps? |
|
|
| 20 |
| 00:01:35,000 --> 00:01:37,000 |
| Should we handle the same error in different places? |
|
|
| 21 |
| 00:01:37,000 --> 00:01:43,000 |
| Or we can find a way to create an exception handler for multiple connected steps during Lutece writing |
|
|
| 22 |
| 00:01:43,000 --> 00:01:43,000 |
| processes. |
|
|
| 23 |
| 00:01:44,000 --> 00:01:46,000 |
| Committable Future helps us to solve this issue. |
|
|
| 24 |
| 00:01:46,000 --> 00:01:53,000 |
| And even more compatible future was released in Java Version eight to improve future interface. |
|
|
| 25 |
| 00:01:53,000 --> 00:01:57,000 |
| Future Interface was released in Java Version five. |
|
|
| 26 |
| 00:01:57,000 --> 00:02:03,000 |
| It was a great improvement, but its introduction doesn't solve an issue of connecting multiple tasks |
|
|
| 27 |
| 00:02:03,000 --> 00:02:09,000 |
| between each other and API for error handling, along with future interface composable. |
|
|
| 28 |
| 00:02:09,000 --> 00:02:14,000 |
| Future also implements another interface that was introduced in Java version eight. |
|
|
| 29 |
| 00:02:15,000 --> 00:02:16,000 |
| It is called Completion Stage. |
|
|
| 30 |
| 00:02:17,000 --> 00:02:19,000 |
| This time defines the context for behavior. |
|
|
| 31 |
| 00:02:19,000 --> 00:02:26,000 |
| For an asynchronous computation step is that we combine with other steps in the source code of this |
|
|
| 32 |
| 00:02:26,000 --> 00:02:28,000 |
| type and we find a lot of different methods. |
|
|
| 33 |
| 00:02:28,000 --> 00:02:30,000 |
| Most of them are overloaded. |
|
|
| 34 |
| 00:02:30,000 --> 00:02:37,000 |
| So implementation of completion, stage and future interfaces in complete the future gives us around |
|
|
| 35 |
| 00:02:37,000 --> 00:02:43,000 |
| 50 masses available to use those methods primarily for composing, combining, executing asynchronous |
|
|
| 36 |
| 00:02:43,000 --> 00:02:45,000 |
| tasks and error handling. |
|
|
| 37 |
| 00:02:46,000 --> 00:02:49,000 |
| Let's start watching compatible future code examples. |
|
|
| 38 |
| 00:02:49,000 --> 00:02:53,000 |
| I create a separate package for examples only was complete the future. |
|
|
| 39 |
| 00:02:53,000 --> 00:02:58,000 |
| I share the length of the package with you in attachments to this in the name No. |
|
|
| 40 |
| 00:02:58,000 --> 00:03:03,000 |
| One, I'm going to show you the simplest and probably one of the most popular usage of compressible |
|
|
| 41 |
| 00:03:03,000 --> 00:03:03,000 |
| future. |
|
|
| 42 |
| 00:03:04,000 --> 00:03:07,000 |
| It is super easy to run asynchronous tasks with this type. |
|
|
| 43 |
| 00:03:08,000 --> 00:03:14,000 |
| It has multiple static masses that allow us to execute task in a separate thread without long configuration |
|
|
| 44 |
| 00:03:14,000 --> 00:03:19,000 |
| of a solid object or creation of executive service and shutting down it later in the case. |
|
|
| 45 |
| 00:03:19,000 --> 00:03:22,000 |
| I just want to execute asynchronous task. |
|
|
| 46 |
| 00:03:22,000 --> 00:03:25,000 |
| I just could run a static method of compostable feature class. |
|
|
| 47 |
| 00:03:26,000 --> 00:03:26,000 |
| That's it. |
|
|
| 48 |
| 00:03:27,000 --> 00:03:32,000 |
| For example, you just need to notify another service about work being started or done and you don't |
|
|
| 49 |
| 00:03:32,000 --> 00:03:34,000 |
| care about response from the client. |
|
|
| 50 |
| 00:03:35,000 --> 00:03:41,000 |
| Such a similar case cases may happen sometimes when you call around asking for joint command post is |
|
|
| 51 |
| 00:03:41,000 --> 00:03:42,000 |
| used. |
|
|
| 52 |
| 00:03:42,000 --> 00:03:49,000 |
| This approach is good for intensive and fast tasks, considering the fact when Java process is finished, |
|
|
| 53 |
| 00:03:49,000 --> 00:03:50,000 |
| there is no common pool. |
|
|
| 54 |
| 00:03:50,000 --> 00:03:56,000 |
| I put sleep here to let this thread be executed and bring this tax to consult run. |
|
|
| 55 |
| 00:03:56,000 --> 00:03:58,000 |
| I think massive is overloaded. |
|
|
| 56 |
| 00:03:58,000 --> 00:04:02,000 |
| There is a massive that takes Runnable object and executor as a method of argument. |
|
|
| 57 |
| 00:04:03,000 --> 00:04:09,000 |
| In the next example here, I put the same lambda function for Runnable and Executive Service, considering |
|
|
| 58 |
| 00:04:09,000 --> 00:04:16,000 |
| the fact that the second example here use a separate executive service and doesn't use for common pool, |
|
|
| 59 |
| 00:04:16,000 --> 00:04:18,000 |
| I don't need to put any sleep here. |
|
|
| 60 |
| 00:04:18,000 --> 00:04:19,000 |
| I'm not afraid. |
|
|
| 61 |
| 00:04:19,000 --> 00:04:21,000 |
| Java process termination. |
|
|
| 62 |
| 00:04:21,000 --> 00:04:27,000 |
| And you can see in console, thread, name and console output that imitates Sambrook that may be done |
|
|
| 63 |
| 00:04:27,000 --> 00:04:30,000 |
| in a separate track by the thread name. |
|
|
| 64 |
| 00:04:30,000 --> 00:04:34,000 |
| You can understand that surrounds is executed with the help of Fajon pull. |
|
|
| 65 |
| 00:04:34,000 --> 00:04:39,000 |
| Make sure you watched my lesson about, for example, if you want them more about. |
|
|
| 66 |
| 00:04:40,000 --> 00:04:43,000 |
| In the second case we use Red Bull executer. |
|
|
| 67 |
| 00:04:43,000 --> 00:04:45,000 |
| That's why Swed name is different. |
|
|
| 68 |
| 00:04:45,000 --> 00:04:46,000 |
| That's it. |
|
|
| 69 |
| 00:04:46,000 --> 00:04:47,000 |
| We're getting this example. |
|
|
| 70 |
| 00:04:47,000 --> 00:04:48,000 |
| Let's move on. |
|
|
| 71 |
| 00:04:49,000 --> 00:04:55,000 |
| The next example is related was one of the features of computable future type you can complete task |
|
|
| 72 |
| 00:04:55,000 --> 00:04:56,000 |
| was method. |
|
|
| 73 |
| 00:04:56,000 --> 00:05:01,000 |
| To be honest, I have never used this method besides learning and educational purposes. |
|
|
| 74 |
| 00:05:01,000 --> 00:05:07,000 |
| But this message is like one of the main sinks, incompatible future when you potentially need to use |
|
|
| 75 |
| 00:05:07,000 --> 00:05:11,000 |
| it, let's say you need to fetch some data from another server. |
|
|
| 76 |
| 00:05:11,000 --> 00:05:13,000 |
| Does this operation would take some time? |
|
|
| 77 |
| 00:05:14,000 --> 00:05:17,000 |
| That's why you decided to run this task in a separate thread. |
|
|
| 78 |
| 00:05:17,000 --> 00:05:22,000 |
| But something happened and the remote server doesn't respond for a specific amount of time. |
|
|
| 79 |
| 00:05:23,000 --> 00:05:25,000 |
| And you really need to proceed with execution. |
|
|
| 80 |
| 00:05:25,000 --> 00:05:29,000 |
| In this case, you may complete the future by returning the default value. |
|
|
| 81 |
| 00:05:29,000 --> 00:05:34,000 |
| Let's look at the example I want to put into console result of a asynchronous calculation. |
|
|
| 82 |
| 00:05:35,000 --> 00:05:38,000 |
| I call calculate calculator sink as it returns any future object. |
|
|
| 83 |
| 00:05:39,000 --> 00:05:43,000 |
| And considering the fact that it's completed all the future implements future interface. |
|
|
| 84 |
| 00:05:43,000 --> 00:05:46,000 |
| I can return composable future when needed. |
|
|
| 85 |
| 00:05:46,000 --> 00:05:49,000 |
| I create an instance of complete double future. |
|
|
| 86 |
| 00:05:49,000 --> 00:05:53,000 |
| After that I create cash, streetball and submit callable for execution. |
|
|
| 87 |
| 00:05:54,000 --> 00:05:56,000 |
| I imitate a call to external server. |
|
|
| 88 |
| 00:05:57,000 --> 00:06:02,000 |
| Imagine that I want to get some price double values that I will assign to the result variable and will |
|
|
| 89 |
| 00:06:02,000 --> 00:06:05,000 |
| return it by making my sleep. |
|
|
| 90 |
| 00:06:05,000 --> 00:06:08,000 |
| I imitate the delay in request a server. |
|
|
| 91 |
| 00:06:09,000 --> 00:06:13,000 |
| After that I shut down executive service and I call a termination. |
|
|
| 92 |
| 00:06:14,000 --> 00:06:18,000 |
| I am waiting for two seconds, only having the reference to the future object. |
|
|
| 93 |
| 00:06:18,000 --> 00:06:22,000 |
| I can verify whether all calculations are done or not done. |
|
|
| 94 |
| 00:06:23,000 --> 00:06:26,000 |
| If calculations are done, I return the reference to the future object. |
|
|
| 95 |
| 00:06:27,000 --> 00:06:32,000 |
| If calculations are not done, I call complete Masset on my accomplishable future object and they pass |
|
|
| 96 |
| 00:06:32,000 --> 00:06:35,000 |
| some default price values that I'm happy to return. |
|
|
| 97 |
| 00:06:36,000 --> 00:06:43,000 |
| In this case, future won't be done and we are going to have force here because we await termination |
|
|
| 98 |
| 00:06:43,000 --> 00:06:45,000 |
| only for two seconds. |
|
|
| 99 |
| 00:06:45,000 --> 00:06:51,000 |
| But we expect tasks to be completed in five seconds after call and complete Masset completed. |
|
|
| 100 |
| 00:06:51,000 --> 00:06:56,000 |
| All future will be considered as completed and I return the reference to the compatible future. |
|
|
| 101 |
| 00:06:56,000 --> 00:07:02,000 |
| When I get the reference to the future, I just called Get MassArt and I extract complete result. |
|
|
| 102 |
| 00:07:03,000 --> 00:07:08,000 |
| Let's run this program and you can see that in console we have nine point ninety nine. |
|
|
| 103 |
| 00:07:08,000 --> 00:07:12,000 |
| This is our default price and we don't get new value. |
|
|
| 104 |
| 00:07:12,000 --> 00:07:17,000 |
| Is it clear if no, ask question below this video and I will be happy to answer. |
|
|
| 105 |
| 00:07:18,000 --> 00:07:20,000 |
| If everything is clear for you, then let's proceed. |
|
|
| 106 |
| 00:07:21,000 --> 00:07:25,000 |
| The next example is located in the file was named Elmasry. |
|
|
| 107 |
| 00:07:25,000 --> 00:07:27,000 |
| This time I'm going to show your supply. |
|
|
| 108 |
| 00:07:27,000 --> 00:07:34,000 |
| I think similar to the run, I think said we can submit a task without boilerplate code. |
|
|
| 109 |
| 00:07:35,000 --> 00:07:41,000 |
| But the only difference is that in releasing we passed Runnable object and here we need to pass supplier. |
|
|
| 110 |
| 00:07:42,000 --> 00:07:47,000 |
| In case you're not familiar with supplier type, feel free to watch my course about functional programming |
|
|
| 111 |
| 00:07:47,000 --> 00:07:48,000 |
| for Java engineers. |
|
|
| 112 |
| 00:07:49,000 --> 00:07:55,000 |
| In that course, we have plenty of examples that will help you to understand a lot of functional interfaces, |
|
|
| 113 |
| 00:07:55,000 --> 00:07:56,000 |
| including supply. |
|
|
| 114 |
| 00:07:57,000 --> 00:07:58,000 |
| Basically, that's it. |
|
|
| 115 |
| 00:07:59,000 --> 00:08:00,000 |
| Supply returns the value. |
|
|
| 116 |
| 00:08:00,000 --> 00:08:07,000 |
| That's why I can get future after Colen supply, async and extract result from it. |
|
|
| 117 |
| 00:08:07,000 --> 00:08:10,000 |
| Let's run this program and print result the console. |
|
|
| 118 |
| 00:08:11,000 --> 00:08:17,000 |
| And as you can see in console, I managed to extract text from the future object and printed it to console. |
|
|
| 119 |
| 00:08:17,000 --> 00:08:23,000 |
| So feel free to use this method in case you have something to execute in a separate thread and you need |
|
|
| 120 |
| 00:08:23,000 --> 00:08:27,000 |
| to get the result of the execution hub that this example is clear. |
|
|
| 121 |
| 00:08:28,000 --> 00:08:29,000 |
| Let's move on now. |
|
|
| 122 |
| 00:08:29,000 --> 00:08:35,000 |
| We'll create with you a sequence of steps that should be executed one after another in a separate thread, |
|
|
| 123 |
| 00:08:36,000 --> 00:08:42,000 |
| because it might happen that you need to perform another action based on the previous step completion. |
|
|
| 124 |
| 00:08:42,000 --> 00:08:48,000 |
| So basically you can act complete about future, which should automatically get called once the future |
|
|
| 125 |
| 00:08:48,000 --> 00:08:48,000 |
| completes. |
|
|
| 126 |
| 00:08:49,000 --> 00:08:51,000 |
| Z is also often called a callback. |
|
|
| 127 |
| 00:08:52,000 --> 00:08:55,000 |
| It is also known as call after function. |
|
|
| 128 |
| 00:08:55,000 --> 00:09:00,000 |
| We have three methods that allow us to do this, then apply, then accept. |
|
|
| 129 |
| 00:09:00,000 --> 00:09:04,000 |
| Xinran, we're going to review examples with these methods. |
|
|
| 130 |
| 00:09:04,000 --> 00:09:11,000 |
| Now, let's start from then apply method in the file demo for I create super simple example to help |
|
|
| 131 |
| 00:09:11,000 --> 00:09:13,000 |
| easily understand how this works. |
|
|
| 132 |
| 00:09:13,000 --> 00:09:18,000 |
| The pardon is the same so you can apply it to any other tasks and calculations. |
|
|
| 133 |
| 00:09:19,000 --> 00:09:26,000 |
| Imagine that you want to fetch user iji by email from one API and once you have user ID, you can request |
|
|
| 134 |
| 00:09:26,000 --> 00:09:33,000 |
| total number of purchases for this user from another API and you need the result of first task execution |
|
|
| 135 |
| 00:09:34,000 --> 00:09:41,000 |
| to get a D in order to be able to execute the second request I call supply asking to submit my first |
|
|
| 136 |
| 00:09:41,000 --> 00:09:41,000 |
| task. |
|
|
| 137 |
| 00:09:42,000 --> 00:09:49,000 |
| Is this a supplier that produces some result and after that I call then apply method and pass a function |
|
|
| 138 |
| 00:09:49,000 --> 00:09:56,000 |
| that takes result of previous task execution as an input argument and that returns as a value. |
|
|
| 139 |
| 00:09:56,000 --> 00:10:01,000 |
| I have console output in first and in second task just to imitate. |
|
|
| 140 |
| 00:10:02,000 --> 00:10:08,000 |
| As a result of then applying, Masset is a future object that you can use to retrieve a result of computation |
|
|
| 141 |
| 00:10:08,000 --> 00:10:15,000 |
| of the last step, you can build multiple steps like this, Michael, and then apply and to use in the |
|
|
| 142 |
| 00:10:15,000 --> 00:10:20,000 |
| result of execution from previous step as an input argument for the next step. |
|
|
| 143 |
| 00:10:20,000 --> 00:10:21,000 |
| Is that clear? |
|
|
| 144 |
| 00:10:21,000 --> 00:10:23,000 |
| If yes, then great. |
|
|
| 145 |
| 00:10:24,000 --> 00:10:27,000 |
| Also, there is another similar method then apply. |
|
|
| 146 |
| 00:10:27,000 --> 00:10:27,000 |
| I think. |
|
|
| 147 |
| 00:10:28,000 --> 00:10:30,000 |
| What would be the difference between then apply and then apply? |
|
|
| 148 |
| 00:10:30,000 --> 00:10:38,000 |
| I think basically the main difference is the executor as it is used to execute these tasks by default, |
|
|
| 149 |
| 00:10:38,000 --> 00:10:44,000 |
| then apply method uses the same threat that was used by the first task and uses the same exact as it |
|
|
| 150 |
| 00:10:44,000 --> 00:10:48,000 |
| was defined by computable future on which it is called. |
|
|
| 151 |
| 00:10:48,000 --> 00:10:52,000 |
| Then apply, I think uses independent executor by default. |
|
|
| 152 |
| 00:10:53,000 --> 00:10:59,000 |
| It is forgery and common pool, but there is an overloaded method that allows it to pass executor service |
|
|
| 153 |
| 00:11:00,000 --> 00:11:03,000 |
| like in the similar example below that will bring us to the same result. |
|
|
| 154 |
| 00:11:04,000 --> 00:11:06,000 |
| I use executive service and then apply. |
|
|
| 155 |
| 00:11:06,000 --> 00:11:12,000 |
| I think Massett in general, if you have multiple tasks for execution, I would just recommend it to |
|
|
| 156 |
| 00:11:12,000 --> 00:11:18,000 |
| have executive service configured and use it for tasks execution that's triggered and then apply. |
|
|
| 157 |
| 00:11:18,000 --> 00:11:20,000 |
| Masset, let's move on. |
|
|
| 158 |
| 00:11:20,000 --> 00:11:22,000 |
| I open them a file file. |
|
|
| 159 |
| 00:11:22,000 --> 00:11:28,000 |
| So as you already understood, then apply method returns to some future object. |
|
|
| 160 |
| 00:11:28,000 --> 00:11:33,000 |
| But in case you don't want to create a return statement to return the result of the execution after |
|
|
| 161 |
| 00:11:33,000 --> 00:11:40,000 |
| the final step and you just need to have some code got executed, you have to use it and accept us run. |
|
|
| 162 |
| 00:11:41,000 --> 00:11:42,000 |
| We we're going to talk in a minute. |
|
|
| 163 |
| 00:11:42,000 --> 00:11:44,000 |
| What is the difference between these two? |
|
|
| 164 |
| 00:11:44,000 --> 00:11:46,000 |
| Let me just start explaining of that. |
|
|
| 165 |
| 00:11:46,000 --> 00:11:53,000 |
| Except first, in this case, imagine that we need to extract full and complete user profile and in |
|
|
| 166 |
| 00:11:53,000 --> 00:11:58,000 |
| the first step of this process, received text representation of user profile. |
|
|
| 167 |
| 00:11:58,000 --> 00:12:05,000 |
| And after that, I just call then accept method to perform some operations that doesn't require me to |
|
|
| 168 |
| 00:12:05,000 --> 00:12:06,000 |
| return the result. |
|
|
| 169 |
| 00:12:06,000 --> 00:12:12,000 |
| For example, just saving this information somewhere in the application, probably in the user session |
|
|
| 170 |
| 00:12:12,000 --> 00:12:18,000 |
| object or in local database, it doesn't matter, for example, then accept also returns compatible |
|
|
| 171 |
| 00:12:18,000 --> 00:12:19,000 |
| future. |
|
|
| 172 |
| 00:12:19,000 --> 00:12:23,000 |
| But this is compatible future that this parametrized by void type. |
|
|
| 173 |
| 00:12:23,000 --> 00:12:29,000 |
| In case you would try to extract value from this future, you would get no, let's run this program. |
|
|
| 174 |
| 00:12:30,000 --> 00:12:35,000 |
| And as you can see in console, I prefer that the console now so we can say that extract value from |
|
|
| 175 |
| 00:12:35,000 --> 00:12:40,000 |
| the future after Colon's and accept doesn't make a lot of sense. |
|
|
| 176 |
| 00:12:40,000 --> 00:12:46,000 |
| Similar to the previous example then, except MassArt has methods that allow to use separate executer |
|
|
| 177 |
| 00:12:46,000 --> 00:12:52,000 |
| for each step, then accept async Macit use a separate executer for tasks execution. |
|
|
| 178 |
| 00:12:52,000 --> 00:12:53,000 |
| Is it clear? |
|
|
| 179 |
| 00:12:54,000 --> 00:12:59,000 |
| Now let's look at the next example with Iran Masset and understand how it is different. |
|
|
| 180 |
| 00:13:00,000 --> 00:13:07,000 |
| I open domestiques, almost similar example, but in this case I just want to see user profile to another |
|
|
| 181 |
| 00:13:07,000 --> 00:13:07,000 |
| server. |
|
|
| 182 |
| 00:13:08,000 --> 00:13:13,000 |
| And once this task will be executed, I want to look that user profile has been saved, but perform |
|
|
| 183 |
| 00:13:13,000 --> 00:13:15,000 |
| any other actions after the first one. |
|
|
| 184 |
| 00:13:16,000 --> 00:13:22,000 |
| In this case, there is no need for me to call supply async because the result of computation of the |
|
|
| 185 |
| 00:13:22,000 --> 00:13:25,000 |
| first step will not be passed to anywhere. |
|
|
| 186 |
| 00:13:25,000 --> 00:13:31,000 |
| That's why it wouldn't matter at all what value will be returned from the first step of the execution. |
|
|
| 187 |
| 00:13:31,000 --> 00:13:38,000 |
| And after it I just called and run method to perform some actions in this case just to notify the user. |
|
|
| 188 |
| 00:13:38,000 --> 00:13:44,000 |
| Profile has been saved and I can proceed with other operations that were dependent on the first one. |
|
|
| 189 |
| 00:13:45,000 --> 00:13:50,000 |
| And again, we are future objects rechanneled, but it contains nothing in response. |
|
|
| 190 |
| 00:13:50,000 --> 00:13:54,000 |
| And also we have similar Massata then run, which is called Zinda Run. |
|
|
| 191 |
| 00:13:54,000 --> 00:14:01,000 |
| I think this method will use separate executive service either for example or the ones at the specified |
|
|
| 192 |
| 00:14:02,000 --> 00:14:05,000 |
| hope that you understand now how to work with these matters. |
|
|
| 193 |
| 00:14:05,000 --> 00:14:06,000 |
| Let's continue. |
|
|
| 194 |
| 00:14:07,000 --> 00:14:10,000 |
| I'd like to talk about a combination of different future objects. |
|
|
| 195 |
| 00:14:11,000 --> 00:14:12,000 |
| I open them. |
|
|
| 196 |
| 00:14:12,000 --> 00:14:18,000 |
| A seven file imagines that you already have two masses and both of them return complete the future object. |
|
|
| 197 |
| 00:14:19,000 --> 00:14:27,000 |
| The first method extracts user details by ID and the second method extracts credit rating by user details. |
|
|
| 198 |
| 00:14:27,000 --> 00:14:30,000 |
| You already know how to use and apply MassArt. |
|
|
| 199 |
| 00:14:30,000 --> 00:14:36,000 |
| Let's look how it would look like in this case when you would call one method and after that you would |
|
|
| 200 |
| 00:14:36,000 --> 00:14:42,000 |
| call another method that also the Transcom political future you would get as a result compatible future. |
|
|
| 201 |
| 00:14:42,000 --> 00:14:44,000 |
| That is parametrized by compatible future. |
|
|
| 202 |
| 00:14:45,000 --> 00:14:47,000 |
| It is not too convenient to work with the result. |
|
|
| 203 |
| 00:14:47,000 --> 00:14:54,000 |
| Now you should call get method twice to extract the results that you wanted, especially for such cases. |
|
|
| 204 |
| 00:14:54,000 --> 00:14:58,000 |
| There is a composed method in case I call them compose. |
|
|
| 205 |
| 00:14:58,000 --> 00:15:00,000 |
| Instead of apply, I get complete. |
|
|
| 206 |
| 00:15:01,000 --> 00:15:03,000 |
| Future parametrized by the time of my results. |
|
|
| 207 |
| 00:15:04,000 --> 00:15:05,000 |
| And that's it. |
|
|
| 208 |
| 00:15:05,000 --> 00:15:11,000 |
| This solution is more elegant in case you want to compose one future object out of two. |
|
|
| 209 |
| 00:15:11,000 --> 00:15:19,000 |
| If in those three Mapai in Java, I am sure you remember that there is such as flat map, that mass, |
|
|
| 210 |
| 00:15:19,000 --> 00:15:20,000 |
| it is similar to this one. |
|
|
| 211 |
| 00:15:21,000 --> 00:15:26,000 |
| So you can extract completely a future from another conceivable future and get flat representation of |
|
|
| 212 |
| 00:15:26,000 --> 00:15:27,000 |
| the result. |
|
|
| 213 |
| 00:15:27,000 --> 00:15:31,000 |
| Also in this case, we have one task running after another. |
|
|
| 214 |
| 00:15:31,000 --> 00:15:33,000 |
| So two dependent tasks. |
|
|
| 215 |
| 00:15:33,000 --> 00:15:37,000 |
| We have also similar methods that are called then compose a scene. |
|
|
| 216 |
| 00:15:37,000 --> 00:15:39,000 |
| I believe you already understand. |
|
|
| 217 |
| 00:15:39,000 --> 00:15:41,000 |
| What is the difference then? |
|
|
| 218 |
| 00:15:41,000 --> 00:15:43,000 |
| Compose a scene you separate. |
|
|
| 219 |
| 00:15:43,000 --> 00:15:49,000 |
| Executer let me open them are eight now in the case, two tasks are independent and you just want to |
|
|
| 220 |
| 00:15:49,000 --> 00:15:53,000 |
| complete two of them in any order you can call them combine. |
|
|
| 221 |
| 00:15:53,000 --> 00:15:58,000 |
| In this case you can perform some actions after two tasks are completed. |
|
|
| 222 |
| 00:15:58,000 --> 00:16:02,000 |
| So again, we have to masset that return complete double future. |
|
|
| 223 |
| 00:16:02,000 --> 00:16:06,000 |
| One method returns weight and another method which is height. |
|
|
| 224 |
| 00:16:07,000 --> 00:16:10,000 |
| Each massive sleep for one second inside. |
|
|
| 225 |
| 00:16:10,000 --> 00:16:17,000 |
| This is just to imitate some operation time in the main mass that we get weight in KG future, and after |
|
|
| 226 |
| 00:16:17,000 --> 00:16:22,000 |
| that we call them combined Masset and we pass height in centimeters future. |
|
|
| 227 |
| 00:16:22,000 --> 00:16:29,000 |
| That together with my function, as you remember, my function can take two arguments and returns. |
|
|
| 228 |
| 00:16:29,000 --> 00:16:34,000 |
| The result, these two arguments would be the result of these two future objects. |
|
|
| 229 |
| 00:16:34,000 --> 00:16:39,000 |
| And once we get the result, we apply the function inside the BI function. |
|
|
| 230 |
| 00:16:39,000 --> 00:16:44,000 |
| I want to calculate the body mass index by following a specific formula here. |
|
|
| 231 |
| 00:16:44,000 --> 00:16:51,000 |
| Let's run the program and you can see in concert that after and weight and height I start calculating |
|
|
| 232 |
| 00:16:51,000 --> 00:16:52,000 |
| body mass index. |
|
|
| 233 |
| 00:16:53,000 --> 00:16:58,000 |
| And the main thing here is that I don't need to have connection between execution of the first and the |
|
|
| 234 |
| 00:16:58,000 --> 00:17:02,000 |
| second task that can be executed in parallel. |
|
|
| 235 |
| 00:17:02,000 --> 00:17:05,000 |
| But I just need the result of both computations. |
|
|
| 236 |
| 00:17:06,000 --> 00:17:12,000 |
| And for the convention, we have then combined async method, which is overloaded and has a version |
|
|
| 237 |
| 00:17:12,000 --> 00:17:16,000 |
| that was default executer and was a separate executer argument. |
|
|
| 238 |
| 00:17:16,000 --> 00:17:20,000 |
| I open them online file and you already know that. |
|
|
| 239 |
| 00:17:20,000 --> 00:17:25,000 |
| Then combined, MassArt returns the result of computation of the future objects. |
|
|
| 240 |
| 00:17:25,000 --> 00:17:32,000 |
| We have another method that is called Xanax, Sambo's, that instead of by function takes by consumer, |
|
|
| 241 |
| 00:17:32,000 --> 00:17:40,000 |
| that means it doesn't return any value and just consumes the results of execution of two tasks and works |
|
|
| 242 |
| 00:17:40,000 --> 00:17:42,000 |
| with two future objects and return nothing. |
|
|
| 243 |
| 00:17:43,000 --> 00:17:47,000 |
| So in this case, you can see that I supply lambda expressions. |
|
|
| 244 |
| 00:17:47,000 --> 00:17:48,000 |
| It returns first. |
|
|
| 245 |
| 00:17:48,000 --> 00:17:53,000 |
| I call accept the both and after that I supply lambda expressions. |
|
|
| 246 |
| 00:17:53,000 --> 00:17:57,000 |
| It returns the second and we just bring concatenated string to consult. |
|
|
| 247 |
| 00:17:58,000 --> 00:18:04,000 |
| And in case I would extract the value from the future object, I would get no because then accept the |
|
|
| 248 |
| 00:18:04,000 --> 00:18:05,000 |
| most massive returns. |
|
|
| 249 |
| 00:18:05,000 --> 00:18:08,000 |
| Computable future parametrized by voit type. |
|
|
| 250 |
| 00:18:09,000 --> 00:18:16,000 |
| Lets run the program and you can see that I printed concatenated string the new value proofs that my |
|
|
| 251 |
| 00:18:16,000 --> 00:18:17,000 |
| future contains. |
|
|
| 252 |
| 00:18:17,000 --> 00:18:21,000 |
| Nassan also we have similar MassArt foreign conventions. |
|
|
| 253 |
| 00:18:21,000 --> 00:18:24,000 |
| We have then accept both async method. |
|
|
| 254 |
| 00:18:24,000 --> 00:18:30,000 |
| So far I've learned math that allowed us to combine only to complete the future objects. |
|
|
| 255 |
| 00:18:31,000 --> 00:18:36,000 |
| Now we are going to land mass that allow us to combine multiple completive of future objects. |
|
|
| 256 |
| 00:18:37,000 --> 00:18:45,000 |
| There are two masses of and any of both of these masses accept variable arguments of political future |
|
|
| 257 |
| 00:18:45,000 --> 00:18:45,000 |
| type. |
|
|
| 258 |
| 00:18:45,000 --> 00:18:47,000 |
| Let's review these two. |
|
|
| 259 |
| 00:18:47,000 --> 00:18:50,000 |
| I open them more than we have here. |
|
|
| 260 |
| 00:18:50,000 --> 00:18:52,000 |
| Simple, but a very interesting example. |
|
|
| 261 |
| 00:18:53,000 --> 00:18:57,000 |
| We are going to come up with a few more masses that I didn't share with you before. |
|
|
| 262 |
| 00:18:57,000 --> 00:19:03,000 |
| The goal of this example is to create a list of strings and turn them into a capital case. |
|
|
| 263 |
| 00:19:03,000 --> 00:19:04,000 |
| Pretty simple scenario. |
|
|
| 264 |
| 00:19:04,000 --> 00:19:11,000 |
| And we will solve this task with computable future, not because I love complicated things, but just |
|
|
| 265 |
| 00:19:11,000 --> 00:19:15,000 |
| to help you understand this example, I create a list of strings. |
|
|
| 266 |
| 00:19:15,000 --> 00:19:22,000 |
| After that, I create a string from this list I call Map Masset and passing functions that completed |
|
|
| 267 |
| 00:19:22,000 --> 00:19:27,000 |
| the future method returns and you complete the future object as it is already completed with the given |
|
|
| 268 |
| 00:19:27,000 --> 00:19:28,000 |
| value. |
|
|
| 269 |
| 00:19:28,000 --> 00:19:36,000 |
| After that, I then apply Masset for each string and invoke the late uppercase Delate uppercase sleep |
|
|
| 270 |
| 00:19:36,000 --> 00:19:43,000 |
| for a random amount of time, but up to one second and returns the current string in uppercase. |
|
|
| 271 |
| 00:19:44,000 --> 00:19:50,000 |
| This random sleep imitates operation time in case there will be more actions here. |
|
|
| 272 |
| 00:19:50,000 --> 00:19:57,000 |
| After that, we have a list of future objects I call all of Masset and POS array of future objects, |
|
|
| 273 |
| 00:19:57,000 --> 00:20:00,000 |
| considering the fact that all of Masad may accept. |
|
|
| 274 |
| 00:20:00,000 --> 00:20:07,000 |
| The verbal argument, all of matter will reach a new political future that is completed when all of |
|
|
| 275 |
| 00:20:07,000 --> 00:20:10,000 |
| the give and complete futures complete. |
|
|
| 276 |
| 00:20:10,000 --> 00:20:17,000 |
| But what would happen in case one of the given futures complete, exceptionally Zenzi complete political |
|
|
| 277 |
| 00:20:17,000 --> 00:20:24,000 |
| future also does so as a result, if any of the given political futures are not reflected in the return |
|
|
| 278 |
| 00:20:24,000 --> 00:20:29,000 |
| to complete the future, but may be obtained by inspecting them individually. |
|
|
| 279 |
| 00:20:30,000 --> 00:20:33,000 |
| After that, I call one complete MassArt. |
|
|
| 280 |
| 00:20:33,000 --> 00:20:40,000 |
| This message returns and you completion stage with the same result of exception as the stage and executes |
|
|
| 281 |
| 00:20:40,000 --> 00:20:41,000 |
| that given action. |
|
|
| 282 |
| 00:20:41,000 --> 00:20:49,000 |
| When this stage completes one complete takes by consumer as method argument in this by consumer receives |
|
|
| 283 |
| 00:20:49,000 --> 00:20:56,000 |
| the result on now if none and the exception on now if none of the stages arguments to get the results, |
|
|
| 284 |
| 00:20:56,000 --> 00:21:00,000 |
| we need to go over our features one more time. |
|
|
| 285 |
| 00:21:00,000 --> 00:21:07,000 |
| In this case, I just print each updated string to console pay attention that I could get now masset |
|
|
| 286 |
| 00:21:07,000 --> 00:21:08,000 |
| of complete double future. |
|
|
| 287 |
| 00:21:09,000 --> 00:21:11,000 |
| We didn't discuss this method yet. |
|
|
| 288 |
| 00:21:11,000 --> 00:21:18,000 |
| Get now returns the value if computation is finished and returns default values that we pass as a method |
|
|
| 289 |
| 00:21:18,000 --> 00:21:20,000 |
| argument if result is not ready. |
|
|
| 290 |
| 00:21:20,000 --> 00:21:23,000 |
| In our case we use one complete Macit. |
|
|
| 291 |
| 00:21:23,000 --> 00:21:28,000 |
| So we assume that all of the features were done by this moment in our program. |
|
|
| 292 |
| 00:21:28,000 --> 00:21:32,000 |
| So I print all uppercase string to consult. |
|
|
| 293 |
| 00:21:32,000 --> 00:21:33,000 |
| Let me run this program. |
|
|
| 294 |
| 00:21:34,000 --> 00:21:35,000 |
| That's it. |
|
|
| 295 |
| 00:21:36,000 --> 00:21:43,000 |
| Any questions regarding all of Masset leaves them under review in case of any the next them is related |
|
|
| 296 |
| 00:21:43,000 --> 00:21:44,000 |
| to any of method. |
|
|
| 297 |
| 00:21:45,000 --> 00:21:47,000 |
| Let me open them on file here. |
|
|
| 298 |
| 00:21:47,000 --> 00:21:51,000 |
| We have absolutely similar example, but with only one difference. |
|
|
| 299 |
| 00:21:52,000 --> 00:21:59,000 |
| Instead of all of I call any of method here any of Masset returns and you completed all future that |
|
|
| 300 |
| 00:21:59,000 --> 00:22:04,000 |
| is completed when any of the given completed will future complete. |
|
|
| 301 |
| 00:22:04,000 --> 00:22:10,000 |
| So in this case, the first future that will be completed will be printed to cancel. |
|
|
| 302 |
| 00:22:10,000 --> 00:22:16,000 |
| Let me run this program that it I have been processed first and that's it. |
|
|
| 303 |
| 00:22:17,000 --> 00:22:19,000 |
| Nothing else is printed to consult. |
|
|
| 304 |
| 00:22:19,000 --> 00:22:20,000 |
| Does it make sense? |
|
|
| 305 |
| 00:22:20,000 --> 00:22:21,000 |
| Great. |
|
|
| 306 |
| 00:22:21,000 --> 00:22:22,000 |
| Let's proceed. |
|
|
| 307 |
| 00:22:23,000 --> 00:22:28,000 |
| And the last, but not least for today, I am going to show you how to handle exceptions with the help |
|
|
| 308 |
| 00:22:28,000 --> 00:22:29,000 |
| of compatible future. |
|
|
| 309 |
| 00:22:30,000 --> 00:22:35,000 |
| This type allows us to handle errors in a chain of asynchronous computation steps. |
|
|
| 310 |
| 00:22:36,000 --> 00:22:41,000 |
| Instead of having to try catch block, we have handle Masset that receives two arguments. |
|
|
| 311 |
| 00:22:41,000 --> 00:22:47,000 |
| The first one is a result of computation in case all processing was finished successfully, and the |
|
|
| 312 |
| 00:22:47,000 --> 00:22:52,000 |
| second argument is exceptions thrown in case there was some exceptional case. |
|
|
| 313 |
| 00:22:52,000 --> 00:22:58,000 |
| I open them Otwell file in this file we have examples of error handling I supply. |
|
|
| 314 |
| 00:22:58,000 --> 00:23:05,000 |
| I think the next task I have int variables that is equal to five and I divided by zero. |
|
|
| 315 |
| 00:23:06,000 --> 00:23:09,000 |
| We're going to have error if we take exception in this line. |
|
|
| 316 |
| 00:23:09,000 --> 00:23:12,000 |
| But take into account this is a onetime exception. |
|
|
| 317 |
| 00:23:12,000 --> 00:23:19,000 |
| Compiler doesn't warn us about potential Hanlan, but I'm smart enough to handle Masad after the last |
|
|
| 318 |
| 00:23:19,000 --> 00:23:19,000 |
| step. |
|
|
| 319 |
| 00:23:19,000 --> 00:23:23,000 |
| And by the way, you may have multiple steps handle. |
|
|
| 320 |
| 00:23:23,000 --> 00:23:28,000 |
| Masset will catch exception on any step of execution in case there are no exceptions. |
|
|
| 321 |
| 00:23:29,000 --> 00:23:35,000 |
| Result of execution would be in the first argument and in case a recent exception, I have the reference |
|
|
| 322 |
| 00:23:35,000 --> 00:23:40,000 |
| to the exception object passed as a second argument that surrounds this program. |
|
|
| 323 |
| 00:23:41,000 --> 00:23:44,000 |
| And in console output we can see that we enter this. |
|
|
| 324 |
| 00:23:44,000 --> 00:23:52,000 |
| If LOC I printed the class of the exception, it is completion exception and it is caused by arithmetic |
|
|
| 325 |
| 00:23:52,000 --> 00:23:52,000 |
| exception. |
|
|
| 326 |
| 00:23:53,000 --> 00:23:57,000 |
| So we can see how a completion exception is the regional exception. |
|
|
| 327 |
| 00:23:57,000 --> 00:23:59,000 |
| We have also another method for error. |
|
|
| 328 |
| 00:23:59,000 --> 00:24:00,000 |
| Hanlan. |
|
|
| 329 |
| 00:24:00,000 --> 00:24:02,000 |
| It is called exceptionally. |
|
|
| 330 |
| 00:24:02,000 --> 00:24:09,000 |
| The difference is that it takes not by function like handle matter, but it takes function and has parameter |
|
|
| 331 |
| 00:24:09,000 --> 00:24:16,000 |
| of Straubel type is the same way I check exception here and considering the fact that I don't have any |
|
|
| 332 |
| 00:24:16,000 --> 00:24:19,000 |
| result available, I can return some default value, for example. |
|
|
| 333 |
| 00:24:20,000 --> 00:24:21,000 |
| That's it. |
|
|
| 334 |
| 00:24:21,000 --> 00:24:23,000 |
| We learned a lot about the future. |
|
|
| 335 |
| 00:24:24,000 --> 00:24:29,000 |
| In case there is anything else you want to know about compatible future, please ask questions. |
|
|
| 336 |
| 00:24:29,000 --> 00:24:36,000 |
| Now let's recap what we have learned in this lesson, in this lesson we learned complete about future. |
|
|
| 337 |
| 00:24:36,000 --> 00:24:42,000 |
| As I said in the beginning of the lesson, it is very useful class that I use very often when I work |
|
|
| 338 |
| 00:24:42,000 --> 00:24:46,000 |
| with multithreaded, it helps to solve a lot of pain points. |
|
|
| 339 |
| 00:24:46,000 --> 00:24:52,000 |
| We learned different methods that describes how to execute tasks was complete the future also. |
|
|
| 340 |
| 00:24:52,000 --> 00:24:56,000 |
| Now you know what a callback is and how to work with callbacks. |
|
|
| 341 |
| 00:24:56,000 --> 00:25:00,000 |
| With the help of compatible future thought, we managed to build multiple. |
|
|
| 342 |
| 00:25:00,000 --> 00:25:07,000 |
| Step with this writing process and real examples, you saw how we can combine future objects and work |
|
|
| 343 |
| 00:25:07,000 --> 00:25:13,000 |
| with them, and at the end of the lesson, I explained how we can manage exceptions with complete double |
|
|
| 344 |
| 00:25:13,000 --> 00:25:13,000 |
| future time. |
|
|
| 345 |
| 00:25:14,000 --> 00:25:15,000 |
| That's all for this lesson. |
|
|
| 346 |
| 00:25:16,000 --> 00:25:17,000 |
| Thanks a lot for your attention. |
|
|
| 347 |
| 00:25:17,000 --> 00:25:20,000 |
| Have a great day and see you in the next lesson. |
|
|
|
|