| 1 |
| 00:00:05,000 --> 00:00:09,000 |
| How are the students in this lesson, we are going to learn the basics of synchronization. |
|
|
| 2 |
| 00:00:10,000 --> 00:00:14,000 |
| Synchronization is a huge topic and we'll learn it with you during multiple lessons. |
|
|
| 3 |
| 00:00:15,000 --> 00:00:20,000 |
| This is the first lesson about stress and presentations that will give you basic knowledge when you |
|
|
| 4 |
| 00:00:20,000 --> 00:00:22,000 |
| create concurrent programs. |
|
|
| 5 |
| 00:00:22,000 --> 00:00:28,000 |
| One of the most important things that you should care about is a synchronized access of multiple threats |
|
|
| 6 |
| 00:00:28,000 --> 00:00:29,000 |
| to the critical errors. |
|
|
| 7 |
| 00:00:30,000 --> 00:00:36,000 |
| What is critical sections will learn with you today in this lesson also will learn with your concepts |
|
|
| 8 |
| 00:00:36,000 --> 00:00:37,000 |
| of monitor and mutex. |
|
|
| 9 |
| 00:00:38,000 --> 00:00:43,000 |
| After this lesson, you will understand these two concepts where, well, I will explain to you what |
|
|
| 10 |
| 00:00:43,000 --> 00:00:46,000 |
| is at tormey cooperation and what is not. |
|
|
| 11 |
| 00:00:46,000 --> 00:00:53,000 |
| Once you understand, all this theory will jump to practical examples and will create our first program |
|
|
| 12 |
| 00:00:53,000 --> 00:00:54,000 |
| with synchronized threats. |
|
|
| 13 |
| 00:00:54,000 --> 00:01:00,000 |
| I will explain how a synchronized keyboard works with Marcedes, and at the end of the lesson I will |
|
|
| 14 |
| 00:01:00,000 --> 00:01:04,000 |
| explain such methods as a way to notify and notify all. |
|
|
| 15 |
| 00:01:04,000 --> 00:01:07,000 |
| All objects in Java have these methods. |
|
|
| 16 |
| 00:01:07,000 --> 00:01:09,000 |
| Let's start to begin with. |
|
|
| 17 |
| 00:01:09,000 --> 00:01:12,000 |
| Let's understand what a critical section is. |
|
|
| 18 |
| 00:01:12,000 --> 00:01:18,000 |
| It is important for us to learn this first because the rest of what we are going to do in this lesson |
|
|
| 19 |
| 00:01:18,000 --> 00:01:21,000 |
| is to synchronize access to critical sections. |
|
|
| 20 |
| 00:01:21,000 --> 00:01:25,000 |
| That's why understanding of this term is critically important. |
|
|
| 21 |
| 00:01:25,000 --> 00:01:32,000 |
| Imagine that you have multiple threats that are executed concurrently and there is block of code that |
|
|
| 22 |
| 00:01:32,000 --> 00:01:36,000 |
| theoretically may be available simultaneously for two threats. |
|
|
| 23 |
| 00:01:36,000 --> 00:01:43,000 |
| This means that in some point of time it might happen that two or more threats will interact with some |
|
|
| 24 |
| 00:01:43,000 --> 00:01:49,000 |
| resource simultaneously that may cause mistakes in calculations and data. |
|
|
| 25 |
| 00:01:49,000 --> 00:01:50,000 |
| Inconsistency. |
|
|
| 26 |
| 00:01:50,000 --> 00:01:57,000 |
| In other words, critical section is a group of instructions that should be executed concurrently only |
|
|
| 27 |
| 00:01:57,000 --> 00:02:01,000 |
| by a specific number of threats and performance specific operations. |
|
|
| 28 |
| 00:02:01,000 --> 00:02:08,000 |
| Usually it is one threat, but as we keep learning to read into advanced level, you would understand |
|
|
| 29 |
| 00:02:08,000 --> 00:02:11,000 |
| that sometimes we want to allow multiple threats to perform. |
|
|
| 30 |
| 00:02:11,000 --> 00:02:16,000 |
| One operation was a resource and allow multiple threats to perform another operation. |
|
|
| 31 |
| 00:02:16,000 --> 00:02:22,000 |
| For example, imagine that you have collection, let's say a list operation of the new elements, or |
|
|
| 32 |
| 00:02:22,000 --> 00:02:25,000 |
| at least should not allow other threats. |
|
|
| 33 |
| 00:02:25,000 --> 00:02:32,000 |
| Read value from any index at mass should block access for all of the threats to read elements from specific |
|
|
| 34 |
| 00:02:32,000 --> 00:02:38,000 |
| index, because I can add new element in that position and that would cause there to be read by other |
|
|
| 35 |
| 00:02:38,000 --> 00:02:39,000 |
| threats. |
|
|
| 36 |
| 00:02:39,000 --> 00:02:46,000 |
| At the same time, there is no need to look at the threats in case all threats only read data from my |
|
|
| 37 |
| 00:02:46,000 --> 00:02:49,000 |
| array list and don't change its state. |
|
|
| 38 |
| 00:02:50,000 --> 00:02:57,000 |
| That's why I may allow as many threats as there exist to read data from our own list only until the |
|
|
| 39 |
| 00:02:57,000 --> 00:03:01,000 |
| moment of adding new elements to contain that will count does it make sense. |
|
|
| 40 |
| 00:03:02,000 --> 00:03:05,000 |
| Now let's understand what is an atomic operation. |
|
|
| 41 |
| 00:03:05,000 --> 00:03:07,000 |
| Atomic comes from Greek word atom. |
|
|
| 42 |
| 00:03:08,000 --> 00:03:12,000 |
| That literally means uncuttable in computer science. |
|
|
| 43 |
| 00:03:12,000 --> 00:03:17,000 |
| Atomic operation is operations that is performed with single processing cycle. |
|
|
| 44 |
| 00:03:17,000 --> 00:03:21,000 |
| In other words, atomic operation is an interrupted operation. |
|
|
| 45 |
| 00:03:22,000 --> 00:03:23,000 |
| Let's understand this, an example. |
|
|
| 46 |
| 00:03:24,000 --> 00:03:29,000 |
| Imagine that you perform an increment of your object's property and you want to update its state. |
|
|
| 47 |
| 00:03:30,000 --> 00:03:34,000 |
| What this thing is, this atomic operation, it is not. |
|
|
| 48 |
| 00:03:34,000 --> 00:03:35,000 |
| Why? |
|
|
| 49 |
| 00:03:35,000 --> 00:03:40,000 |
| Because you have to read values that are stored in the piece of memory dictated to the class property |
|
|
| 50 |
| 00:03:40,000 --> 00:03:41,000 |
| variable first. |
|
|
| 51 |
| 00:03:42,000 --> 00:03:46,000 |
| After that you need to perform an increment and add one. |
|
|
| 52 |
| 00:03:46,000 --> 00:03:51,000 |
| After that, you need to store the result of additions in some place, and only after that you need |
|
|
| 53 |
| 00:03:51,000 --> 00:03:55,000 |
| to assign the result of increments to another variable. |
|
|
| 54 |
| 00:03:55,000 --> 00:03:57,000 |
| Our class property is that clear. |
|
|
| 55 |
| 00:03:58,000 --> 00:04:04,000 |
| So even such simple operation is the first glance like increment is not atomic, but in this case, |
|
|
| 56 |
| 00:04:05,000 --> 00:04:07,000 |
| what is an atomic operation? |
|
|
| 57 |
| 00:04:07,000 --> 00:04:09,000 |
| And simple words read and write. |
|
|
| 58 |
| 00:04:09,000 --> 00:04:11,000 |
| Operations are atomic. |
|
|
| 59 |
| 00:04:11,000 --> 00:04:18,000 |
| For example, assigning value to a variable is atomic operation removal value from array is atomic operation. |
|
|
| 60 |
| 00:04:18,000 --> 00:04:21,000 |
| Assigning value is an atomic operation too. |
|
|
| 61 |
| 00:04:22,000 --> 00:04:29,000 |
| Does it make sense also in general with a special package that contains only Tibs that execute not atomic |
|
|
| 62 |
| 00:04:29,000 --> 00:04:35,000 |
| operations by nature, but actually execute operations that looks like atomic, for example? |
|
|
| 63 |
| 00:04:36,000 --> 00:04:41,000 |
| You know, that increment and addition is not atomic operation by itself, but atomic integer, for |
|
|
| 64 |
| 00:04:41,000 --> 00:04:48,000 |
| example, maybe from addition of another in synchronized manner to not allow any other threat interrupt |
|
|
| 65 |
| 00:04:48,000 --> 00:04:55,000 |
| execution of the separation later in this course, will review is generally two concurrent atomic package |
|
|
| 66 |
| 00:04:55,000 --> 00:04:58,000 |
| that contains such types of perform atomic operations. |
|
|
| 67 |
| 00:04:59,000 --> 00:05:03,000 |
| Would it a great single ready now you know what is an atomic. |
|
|
| 68 |
| 00:05:03,000 --> 00:05:07,000 |
| Atomic operations also know what a critical section is. |
|
|
| 69 |
| 00:05:07,000 --> 00:05:12,000 |
| Let's look at example now so that you can understand the problem of performing non atomic operations |
|
|
| 70 |
| 00:05:12,000 --> 00:05:19,000 |
| with multiple threats and why we need to synchronize access to critical section I open unsynchronized |
|
|
| 71 |
| 00:05:19,000 --> 00:05:20,000 |
| incremented file. |
|
|
| 72 |
| 00:05:20,000 --> 00:05:22,000 |
| Let's look at the main message here. |
|
|
| 73 |
| 00:05:22,000 --> 00:05:29,000 |
| And I will say you before we start that the quote below is a spaghetti code because we don't use executer |
|
|
| 74 |
| 00:05:29,000 --> 00:05:34,000 |
| in this example, considering the fact that by this moment in our course, we don't know. |
|
|
| 75 |
| 00:05:34,000 --> 00:05:40,000 |
| Executor's, I will show you this example was BASIX, Red Cross and Runnable interface that we all know |
|
|
| 76 |
| 00:05:41,000 --> 00:05:46,000 |
| later in this course, we'll show you another solution, which is, in my opinion, more elegant. |
|
|
| 77 |
| 00:05:46,000 --> 00:05:53,000 |
| But I will show it to you once we execute our stoppered hacker, at least that will contain references |
|
|
| 78 |
| 00:05:53,000 --> 00:06:00,000 |
| to ohmy threat objects, because I'm going to create 10000 thread objects when it's so many threads |
|
|
| 79 |
| 00:06:00,000 --> 00:06:07,000 |
| objects to be able to demo issues that may happen in case with performing on atomic operation with multiple |
|
|
| 80 |
| 00:06:07,000 --> 00:06:09,000 |
| threats have falu. |
|
|
| 81 |
| 00:06:09,000 --> 00:06:11,000 |
| And you can see that in condition. |
|
|
| 82 |
| 00:06:11,000 --> 00:06:16,000 |
| I verify that I made 10000 iterations on each iteration. |
|
|
| 83 |
| 00:06:16,000 --> 00:06:21,000 |
| I create a new threat object with the following implementation of Runnable interface. |
|
|
| 84 |
| 00:06:21,000 --> 00:06:27,000 |
| I increment my static int variables that is present in this class and I will perform this increment |
|
|
| 85 |
| 00:06:27,000 --> 00:06:29,000 |
| 10000 times. |
|
|
| 86 |
| 00:06:29,000 --> 00:06:37,000 |
| So what value will be here once all threats will perform increment ten thousand times will look at the |
|
|
| 87 |
| 00:06:37,000 --> 00:06:43,000 |
| answer in the minutes after that and look at reference of this threat to the common list of threats. |
|
|
| 88 |
| 00:06:43,000 --> 00:06:50,000 |
| I need this to be able to request each threat to join main threat and make main threat, wait until |
|
|
| 89 |
| 00:06:50,000 --> 00:06:52,000 |
| all other threats will be executed. |
|
|
| 90 |
| 00:06:53,000 --> 00:07:00,000 |
| And again, you need to see this code to feel relief later when you will start to use executer, because |
|
|
| 91 |
| 00:07:00,000 --> 00:07:05,000 |
| you will understand how executables would simplify interaction with multiple threats. |
|
|
| 92 |
| 00:07:05,000 --> 00:07:09,000 |
| And in Body of the Loop, I start each threat after that. |
|
|
| 93 |
| 00:07:09,000 --> 00:07:14,000 |
| And for each loop I ask each threat, the join main threat and make my main threat. |
|
|
| 94 |
| 00:07:14,000 --> 00:07:18,000 |
| Wait until all other threats will be executed. |
|
|
| 95 |
| 00:07:18,000 --> 00:07:24,000 |
| When all threats did incremented, we can print our variable to cancel and let's see. |
|
|
| 96 |
| 00:07:24,000 --> 00:07:28,000 |
| Instead I will run program multiple times to let you see the issue. |
|
|
| 97 |
| 00:07:29,000 --> 00:07:32,000 |
| Can you see that the result is not always 10000? |
|
|
| 98 |
| 00:07:33,000 --> 00:07:35,000 |
| They understand why this is happening. |
|
|
| 99 |
| 00:07:36,000 --> 00:07:43,000 |
| That is because at some moment of time, two threats enter this method simultaneously and both threats |
|
|
| 100 |
| 00:07:43,000 --> 00:07:48,000 |
| read the same value of counter variable and each threat might increment. |
|
|
| 101 |
| 00:07:48,000 --> 00:07:51,000 |
| But logically, this is two increments. |
|
|
| 102 |
| 00:07:51,000 --> 00:07:58,000 |
| But in fact, once we get our right increment result from as a threat and we got lost update, is it |
|
|
| 103 |
| 00:07:58,000 --> 00:08:02,000 |
| clear now and what to do and how to solve this issue? |
|
|
| 104 |
| 00:08:02,000 --> 00:08:05,000 |
| You already can easily spot where critical section is. |
|
|
| 105 |
| 00:08:06,000 --> 00:08:12,000 |
| We need to synchronize access of different threats to our critical section where we are careful not |
|
|
| 106 |
| 00:08:12,000 --> 00:08:13,000 |
| optronics operation. |
|
|
| 107 |
| 00:08:14,000 --> 00:08:20,000 |
| That's why I started the lesson from explanation of critical sections and atomic operations to make |
|
|
| 108 |
| 00:08:20,000 --> 00:08:25,000 |
| sure that by this moment of time in our lesson, you would understand what I'm talking about. |
|
|
| 109 |
| 00:08:25,000 --> 00:08:28,000 |
| Let's now try to solve this issue. |
|
|
| 110 |
| 00:08:28,000 --> 00:08:35,000 |
| To solve this issue, we need to control concurrent access to the critical area, the basic to enjoy. |
|
|
| 111 |
| 00:08:35,000 --> 00:08:37,000 |
| The key for this is synchronized keyword. |
|
|
| 112 |
| 00:08:38,000 --> 00:08:40,000 |
| Let me open synchronized increment class. |
|
|
| 113 |
| 00:08:41,000 --> 00:08:45,000 |
| This is similar example to the previous one was only one difference. |
|
|
| 114 |
| 00:08:45,000 --> 00:08:48,000 |
| My increment method synchronized keyword here. |
|
|
| 115 |
| 00:08:49,000 --> 00:08:51,000 |
| Let's run our program now multiple times. |
|
|
| 116 |
| 00:08:51,000 --> 00:08:59,000 |
| And you can see now that I constantly have ten thousand and so is it is because this synchronized keyword |
|
|
| 117 |
| 00:08:59,000 --> 00:09:03,000 |
| doesn't allow to stress access is block of code simultaneously. |
|
|
| 118 |
| 00:09:04,000 --> 00:09:07,000 |
| That's why we just eliminated all possible errors. |
|
|
| 119 |
| 00:09:07,000 --> 00:09:10,000 |
| How to synchronize keywords for X. |
|
|
| 120 |
| 00:09:10,000 --> 00:09:14,000 |
| We need to understand this to create more complex solutions with better performance. |
|
|
| 121 |
| 00:09:15,000 --> 00:09:21,000 |
| To understand how to synchronize keyboard works, we need to understand such important concepts in Montessori, |
|
|
| 122 |
| 00:09:21,000 --> 00:09:24,000 |
| in programming as mutex and monitor. |
|
|
| 123 |
| 00:09:24,000 --> 00:09:27,000 |
| Let's start from understanding of what Moneta is. |
|
|
| 124 |
| 00:09:28,000 --> 00:09:33,000 |
| And once we learned what I wanted to ask, how explain the difference between the index and monitor |
|
|
| 125 |
| 00:09:34,000 --> 00:09:36,000 |
| my own definition of monitor. |
|
|
| 126 |
| 00:09:36,000 --> 00:09:42,000 |
| Sounds like this monitor is a mechanism to synchronize threads, access to critical sections. |
|
|
| 127 |
| 00:09:43,000 --> 00:09:50,000 |
| More common definition from Wikipedia also includes other properties of monitor like ability to allow |
|
|
| 128 |
| 00:09:50,000 --> 00:09:55,000 |
| stress to have both mutuel exclusion and the ability to wait for a critical condition. |
|
|
| 129 |
| 00:09:56,000 --> 00:10:02,000 |
| By the way, mutuel exclusion is also churl from computer science and describes the property of. |
|
|
| 130 |
| 00:10:02,000 --> 00:10:09,000 |
| Currency control, which should prevent a race condition by not allowing any threat, entering a political |
|
|
| 131 |
| 00:10:09,000 --> 00:10:15,000 |
| section, if some as a threat currently executing the court of critical section somewhere, you married |
|
|
| 132 |
| 00:10:15,000 --> 00:10:23,000 |
| another definition saying that monitor is a threat, safe class object or module that is partially also |
|
|
| 133 |
| 00:10:23,000 --> 00:10:24,000 |
| makes sense. |
|
|
| 134 |
| 00:10:24,000 --> 00:10:31,000 |
| We can use an object as a flag and as a monitor to indicate which threat captures and monitor of the |
|
|
| 135 |
| 00:10:31,000 --> 00:10:34,000 |
| object and which threat released monitor of the object. |
|
|
| 136 |
| 00:10:35,000 --> 00:10:39,000 |
| So injera monitor is implicitly associated with an object. |
|
|
| 137 |
| 00:10:39,000 --> 00:10:42,000 |
| Let me support my explanation, which was analyzation. |
|
|
| 138 |
| 00:10:43,000 --> 00:10:45,000 |
| Let's look at the example with my car. |
|
|
| 139 |
| 00:10:45,000 --> 00:10:52,000 |
| Here is my only Rs5 that can reach 60 miles per hour in less than a three point five seconds. |
|
|
| 140 |
| 00:10:52,000 --> 00:10:55,000 |
| This has nothing in common with multiscreen and yet. |
|
|
| 141 |
| 00:10:55,000 --> 00:10:56,000 |
| But we will jump to the details. |
|
|
| 142 |
| 00:10:56,000 --> 00:11:01,000 |
| So imagine that this car is a monitor and critical sections. |
|
|
| 143 |
| 00:11:01,000 --> 00:11:06,000 |
| Here are accelerator pedal, brake pedal, steering wheel and so on. |
|
|
| 144 |
| 00:11:07,000 --> 00:11:08,000 |
| I'm a threat. |
|
|
| 145 |
| 00:11:09,000 --> 00:11:12,000 |
| And girlfriend of mine is another threat of execution. |
|
|
| 146 |
| 00:11:13,000 --> 00:11:16,000 |
| Those threats can't simultaneously interact with. |
|
|
| 147 |
| 00:11:17,000 --> 00:11:22,000 |
| It will be horrible sink in case me and your friend of mine will be pushing on different pedals simultaneously. |
|
|
| 148 |
| 00:11:23,000 --> 00:11:27,000 |
| I can capture, monitor and do operations with the cars that they need. |
|
|
| 149 |
| 00:11:28,000 --> 00:11:30,000 |
| I open the car and drive to an office. |
|
|
| 150 |
| 00:11:30,000 --> 00:11:33,000 |
| And when I got back home, I released the monitor. |
|
|
| 151 |
| 00:11:34,000 --> 00:11:40,000 |
| When the monitor is released and a threat, my girlfriend can take it and can go to the beauty salon, |
|
|
| 152 |
| 00:11:40,000 --> 00:11:41,000 |
| for example. |
|
|
| 153 |
| 00:11:41,000 --> 00:11:49,000 |
| Is it clear so far there are also some methods that allow to interact with, monitor their weight, |
|
|
| 154 |
| 00:11:49,000 --> 00:11:51,000 |
| notify and notify all. |
|
|
| 155 |
| 00:11:51,000 --> 00:11:52,000 |
| Wait. |
|
|
| 156 |
| 00:11:52,000 --> 00:11:59,000 |
| MassArt is overloaded and has versions with arguments that time related arguments milliseconds and nanoseconds |
|
|
| 157 |
| 00:12:00,000 --> 00:12:09,000 |
| zest masses inherited in all types from object class because all objects in Java implicitly extant object |
|
|
| 158 |
| 00:12:09,000 --> 00:12:09,000 |
| class. |
|
|
| 159 |
| 00:12:10,000 --> 00:12:11,000 |
| What these methods do. |
|
|
| 160 |
| 00:12:12,000 --> 00:12:13,000 |
| Let's review an example. |
|
|
| 161 |
| 00:12:14,000 --> 00:12:21,000 |
| Imagine that my girlfriend took a car and all of a sudden something happened with a car and it was stopped |
|
|
| 162 |
| 00:12:21,000 --> 00:12:21,000 |
| unexpectedly. |
|
|
| 163 |
| 00:12:22,000 --> 00:12:26,000 |
| She called me and asked me to pick up her with the car and help. |
|
|
| 164 |
| 00:12:26,000 --> 00:12:32,000 |
| When I found her in the city, she went out of the car and let me in what she did. |
|
|
| 165 |
| 00:12:32,000 --> 00:12:37,000 |
| She released more nature of the object temporarily and let me capture monitor. |
|
|
| 166 |
| 00:12:38,000 --> 00:12:44,000 |
| She still has intention to drive further, but she just let me also perform some actions with the car. |
|
|
| 167 |
| 00:12:44,000 --> 00:12:46,000 |
| And that is exactly what the weight method does. |
|
|
| 168 |
| 00:12:46,000 --> 00:12:51,000 |
| It's just really this monitor and let us the capture monitor. |
|
|
| 169 |
| 00:12:51,000 --> 00:12:57,000 |
| I was happy to discover that my girlfriend just didn't activate Immobiliser and the engine appeared |
|
|
| 170 |
| 00:12:57,000 --> 00:12:58,000 |
| to be blocked. |
|
|
| 171 |
| 00:12:58,000 --> 00:13:03,000 |
| I think that and told her that she can drive from wherever she needs. |
|
|
| 172 |
| 00:13:03,000 --> 00:13:11,000 |
| What I did, I called notify Masset on the monitor, notify Masset makes all threats that we're waiting |
|
|
| 173 |
| 00:13:11,000 --> 00:13:14,000 |
| are aware that they can proceed their work. |
|
|
| 174 |
| 00:13:14,000 --> 00:13:21,000 |
| That means we use with Massata to let other threats perform some actions and modify the state of some |
|
|
| 175 |
| 00:13:21,000 --> 00:13:24,000 |
| objects if needed, of some shared resources. |
|
|
| 176 |
| 00:13:24,000 --> 00:13:31,000 |
| And after that, other threats should call notify Masset to update all threats that they've done. |
|
|
| 177 |
| 00:13:32,000 --> 00:13:34,000 |
| Another example of wait and notify. |
|
|
| 178 |
| 00:13:35,000 --> 00:13:39,000 |
| You're going to have coding exercises soon and there will be a task about readers and writers. |
|
|
| 179 |
| 00:13:39,000 --> 00:13:46,000 |
| For example, readers interact with some buffer of memory where readers should find information to read |
|
|
| 180 |
| 00:13:47,000 --> 00:13:52,000 |
| readers captions and monitor of buffer object and doesn't allow anyone to work with it. |
|
|
| 181 |
| 00:13:53,000 --> 00:13:59,000 |
| Once readers read all information from Buffer and Buffer is empty, they're turned into the waiting |
|
|
| 182 |
| 00:13:59,000 --> 00:14:04,000 |
| state and they wait until right to put your information into the buffer. |
|
|
| 183 |
| 00:14:05,000 --> 00:14:11,000 |
| Once the writer finished its job and put all information and buffer it, notifies our readers that we're |
|
|
| 184 |
| 00:14:11,000 --> 00:14:16,000 |
| in a weakened state by and notify all Masset on buffer object. |
|
|
| 185 |
| 00:14:16,000 --> 00:14:20,000 |
| And now readers continue with information from Buffer and so on. |
|
|
| 186 |
| 00:14:20,000 --> 00:14:27,000 |
| Notify all is a matter to notify not only once residents in waiting queue, but notify us all threats |
|
|
| 187 |
| 00:14:27,000 --> 00:14:28,000 |
| that time in the waiting queue. |
|
|
| 188 |
| 00:14:29,000 --> 00:14:33,000 |
| Hope that now you understood what is and wanted to know. |
|
|
| 189 |
| 00:14:33,000 --> 00:14:38,000 |
| Let's understand the difference between two terms monitor and mutex. |
|
|
| 190 |
| 00:14:38,000 --> 00:14:44,000 |
| Conceptually, these two terms are similar zooni difference is how they are implemented inside. |
|
|
| 191 |
| 00:14:45,000 --> 00:14:52,000 |
| Usually the implementation of monitors is faster light weight since it is designed for multiple threaded |
|
|
| 192 |
| 00:14:52,000 --> 00:14:54,000 |
| synchronization within the same process. |
|
|
| 193 |
| 00:14:55,000 --> 00:15:01,000 |
| Also, usually it is provided by a framework library itself and not request the operating system. |
|
|
| 194 |
| 00:15:01,000 --> 00:15:05,000 |
| Usually matrixes are provided by the operating system. |
|
|
| 195 |
| 00:15:05,000 --> 00:15:12,000 |
| Kernell what is always Curnoe in simple words, it is a computer program at the core of the computer's |
|
|
| 196 |
| 00:15:12,000 --> 00:15:16,000 |
| operating system and has complete control over everything in the system. |
|
|
| 197 |
| 00:15:17,000 --> 00:15:21,000 |
| It also handles data processing instructions for the central processing unit. |
|
|
| 198 |
| 00:15:22,000 --> 00:15:27,000 |
| It is a portion of the operating system code that is always resident in memory. |
|
|
| 199 |
| 00:15:28,000 --> 00:15:33,000 |
| Usually libraries frameworks simply provide an interface to invoke mutex. |
|
|
| 200 |
| 00:15:33,000 --> 00:15:40,000 |
| This makes them heavy weight slower, but allows us to achieve expected to result to synchronize threads |
|
|
| 201 |
| 00:15:40,000 --> 00:15:42,000 |
| between each other and lock on. |
|
|
| 202 |
| 00:15:42,000 --> 00:15:49,000 |
| Mutex from neutral exclusion is a mechanism that enforces limits on access to resource. |
|
|
| 203 |
| 00:15:49,000 --> 00:15:55,000 |
| When there are many threats of execution, a lock is designed to enforce a mutual exclusion. |
|
|
| 204 |
| 00:15:55,000 --> 00:16:01,000 |
| Concurrency Control Policy and Monitor consists of a mutex lock object and condition variables. |
|
|
| 205 |
| 00:16:01,000 --> 00:16:07,000 |
| A condition variable essentially is a container of threats that are waiting for a certain condition |
|
|
| 206 |
| 00:16:08,000 --> 00:16:08,000 |
| more. |
|
|
| 207 |
| 00:16:08,000 --> 00:16:14,000 |
| Charters provide a mechanism for threats to temporarily give up exclusive access in order to wait for |
|
|
| 208 |
| 00:16:14,000 --> 00:16:19,000 |
| some conditions to be met before gaining exclusive access and resuming their task. |
|
|
| 209 |
| 00:16:20,000 --> 00:16:26,000 |
| So monitor is different than mutex, but they can be considered similar in the sense that the monitor |
|
|
| 210 |
| 00:16:26,000 --> 00:16:31,000 |
| is built on top of mutex in this lesson we'll use to monitor transfers. |
|
|
| 211 |
| 00:16:31,000 --> 00:16:36,000 |
| But just in case you heard that somebody uses mutex term, you'll really know the difference. |
|
|
| 212 |
| 00:16:37,000 --> 00:16:43,000 |
| Now, let's look at the Korean example and we'll try to understand how monitor works, how synchronization |
|
|
| 213 |
| 00:16:43,000 --> 00:16:47,000 |
| happens and practice example, a way to notify interaction. |
|
|
| 214 |
| 00:16:47,000 --> 00:16:51,000 |
| Let's get back to synchronized examples that we already saw today. |
|
|
| 215 |
| 00:16:51,000 --> 00:16:54,000 |
| There is one more method here that is similar to synchronized one. |
|
|
| 216 |
| 00:16:55,000 --> 00:17:00,000 |
| Pay attention that this method doesn't have synchronized keywords in the same line was messed name, |
|
|
| 217 |
| 00:17:00,000 --> 00:17:02,000 |
| but it contains synchronized block. |
|
|
| 218 |
| 00:17:03,000 --> 00:17:03,000 |
| What is this? |
|
|
| 219 |
| 00:17:04,000 --> 00:17:09,000 |
| So when you have synchronized Masad, it is fair to say that you captured the monitor of this object |
|
|
| 220 |
| 00:17:10,000 --> 00:17:12,000 |
| of object which he used to Vogues and mastered. |
|
|
| 221 |
| 00:17:13,000 --> 00:17:19,000 |
| But what object you used to walk in Inmarsat in this case and also how it works with static methods, |
|
|
| 222 |
| 00:17:19,000 --> 00:17:21,000 |
| with static methods. |
|
|
| 223 |
| 00:17:21,000 --> 00:17:25,000 |
| You capture Moneta of this class to create synchronized block. |
|
|
| 224 |
| 00:17:25,000 --> 00:17:31,000 |
| You have to pass the reference to an object where you want to capture monitor right now. |
|
|
| 225 |
| 00:17:31,000 --> 00:17:33,000 |
| And this block may enter only once read. |
|
|
| 226 |
| 00:17:33,000 --> 00:17:40,000 |
| And once the threat will leave this block, it will release monitor of this class and the next threat |
|
|
| 227 |
| 00:17:40,000 --> 00:17:45,000 |
| will enter this block and will capture monitor, of course, with synchronized methods. |
|
|
| 228 |
| 00:17:45,000 --> 00:17:51,000 |
| That principle is the same, but you just have synchronized access to the whole method, and not only |
|
|
| 229 |
| 00:17:51,000 --> 00:17:56,000 |
| for a specific part of it, why you might want to use synchronize blocks. |
|
|
| 230 |
| 00:17:56,000 --> 00:18:02,000 |
| So this part of the spreading optimization, because it may be that actually not aligned in your methods |
|
|
| 231 |
| 00:18:02,000 --> 00:18:04,000 |
| is a critical section. |
|
|
| 232 |
| 00:18:04,000 --> 00:18:09,000 |
| Probably there are some operations that have multiple threads may perform in parallel. |
|
|
| 233 |
| 00:18:09,000 --> 00:18:11,000 |
| That might be really different cases. |
|
|
| 234 |
| 00:18:11,000 --> 00:18:16,000 |
| For example, here you will print some text to console or you just want to log that. |
|
|
| 235 |
| 00:18:16,000 --> 00:18:22,000 |
| You enter this method and you want to log some message after critical section, or it can be some preparation |
|
|
| 236 |
| 00:18:22,000 --> 00:18:24,000 |
| activities before the duration. |
|
|
| 237 |
| 00:18:24,000 --> 00:18:27,000 |
| Anyway, log in print and text. |
|
|
| 238 |
| 00:18:27,000 --> 00:18:30,000 |
| The console in this case is not a critical section. |
|
|
| 239 |
| 00:18:30,000 --> 00:18:34,000 |
| This will not bring you to inconsistent state of your system. |
|
|
| 240 |
| 00:18:34,000 --> 00:18:41,000 |
| That's why there is no need to make your threats, wait to do operations that they can do now without |
|
|
| 241 |
| 00:18:41,000 --> 00:18:42,000 |
| waiting. |
|
|
| 242 |
| 00:18:42,000 --> 00:18:47,000 |
| So all core outside of the synchronized block may be executed concurrently. |
|
|
| 243 |
| 00:18:48,000 --> 00:18:54,000 |
| When you will create a certain program, always ask yourself, do I need to synchronize access to this |
|
|
| 244 |
| 00:18:54,000 --> 00:19:00,000 |
| chunk of code or know what will happen if the threat will execute this code simultaneously? |
|
|
| 245 |
| 00:19:00,000 --> 00:19:06,000 |
| And in case you discover that nothing bad would happen, do not with this code in synchronized lock, |
|
|
| 246 |
| 00:19:07,000 --> 00:19:12,000 |
| because in this case you would improve performance of your app by not making your sweats. |
|
|
| 247 |
| 00:19:12,000 --> 00:19:12,000 |
| Wait. |
|
|
| 248 |
| 00:19:12,000 --> 00:19:19,000 |
| And when they shouldn't be waiting in general, this is rule of thumb to have a small synchronized block |
|
|
| 249 |
| 00:19:19,000 --> 00:19:19,000 |
| as possible. |
|
|
| 250 |
| 00:19:20,000 --> 00:19:25,000 |
| In case this method won't be static, you will capture monitor of another object. |
|
|
| 251 |
| 00:19:25,000 --> 00:19:32,000 |
| In this case, you would capture monitor of this object, the one that invokes this method. |
|
|
| 252 |
| 00:19:32,000 --> 00:19:34,000 |
| So these two methods now are similar. |
|
|
| 253 |
| 00:19:35,000 --> 00:19:40,000 |
| What potential drawback you see in using synchronize locks with synchronized locks? |
|
|
| 254 |
| 00:19:40,000 --> 00:19:45,000 |
| You can't capture a monitor in one place and release it completely in another place. |
|
|
| 255 |
| 00:19:46,000 --> 00:19:52,000 |
| You can't describe synchronized lock in multiple methods, but there is so called a lock API that we |
|
|
| 256 |
| 00:19:52,000 --> 00:19:54,000 |
| are going to learn all kinds. |
|
|
| 257 |
| 00:19:54,000 --> 00:19:59,000 |
| Of course, that will allow you to capture more data in one place and release it somewhere else. |
|
|
| 258 |
| 00:20:00,000 --> 00:20:06,000 |
| Now let's look at WAF not for example, I grouped all the classes related to this example in a separate |
|
|
| 259 |
| 00:20:06,000 --> 00:20:06,000 |
| package. |
|
|
| 260 |
| 00:20:06,000 --> 00:20:08,000 |
| Here was name with Latifi. |
|
|
| 261 |
| 00:20:09,000 --> 00:20:14,000 |
| Let me open them a file and will start from one could imagine that I have some message. |
|
|
| 262 |
| 00:20:14,000 --> 00:20:19,000 |
| I create object of this type and left some message to process it. |
|
|
| 263 |
| 00:20:19,000 --> 00:20:25,000 |
| Let's have a look at the source code of message type message has one properties and describes its state. |
|
|
| 264 |
| 00:20:26,000 --> 00:20:32,000 |
| It is called message and need this type fostering position because he already knows that string itself |
|
|
| 265 |
| 00:20:32,000 --> 00:20:34,000 |
| immutable object. |
|
|
| 266 |
| 00:20:34,000 --> 00:20:36,000 |
| Once a great object of type string. |
|
|
| 267 |
| 00:20:36,000 --> 00:20:38,000 |
| I can't change it state. |
|
|
| 268 |
| 00:20:39,000 --> 00:20:46,000 |
| That's why I created separate type that has API that allows me to update the state of the same object. |
|
|
| 269 |
| 00:20:46,000 --> 00:20:48,000 |
| Also, there are two matters here. |
|
|
| 270 |
| 00:20:48,000 --> 00:20:49,000 |
| Getter and setter. |
|
|
| 271 |
| 00:20:50,000 --> 00:20:50,000 |
| That's it. |
|
|
| 272 |
| 00:20:51,000 --> 00:20:52,000 |
| Let's get back to the demo file. |
|
|
| 273 |
| 00:20:53,000 --> 00:20:56,000 |
| The second object that I create here is a reader object. |
|
|
| 274 |
| 00:20:56,000 --> 00:20:58,000 |
| I pass a reference to the message object. |
|
|
| 275 |
| 00:20:58,000 --> 00:20:59,000 |
| We are constructor. |
|
|
| 276 |
| 00:21:00,000 --> 00:21:06,000 |
| After that I create a threat object based reference to the readers and name as threat as reader one |
|
|
| 277 |
| 00:21:06,000 --> 00:21:07,000 |
| and start the threat. |
|
|
| 278 |
| 00:21:08,000 --> 00:21:14,000 |
| Probably already understands its rather implements Runnable interface, and you're right where you source |
|
|
| 279 |
| 00:21:14,000 --> 00:21:16,000 |
| code of reading type in a few seconds. |
|
|
| 280 |
| 00:21:17,000 --> 00:21:19,000 |
| Also another reader and pay attention. |
|
|
| 281 |
| 00:21:20,000 --> 00:21:22,000 |
| I pass the same message, object to the constructor. |
|
|
| 282 |
| 00:21:23,000 --> 00:21:26,000 |
| This would be exactly the object that I would use for multiple threads. |
|
|
| 283 |
| 00:21:26,000 --> 00:21:32,000 |
| Synchronization here I create another thread, object to his name reader to and run this thread. |
|
|
| 284 |
| 00:21:33,000 --> 00:21:39,000 |
| So after this line we would have three threads running my main threat and to readers threats. |
|
|
| 285 |
| 00:21:40,000 --> 00:21:44,000 |
| Let's learn what will be executed inside our readers around method. |
|
|
| 286 |
| 00:21:45,000 --> 00:21:49,000 |
| As you can see, reader class implements Runnable Interface. |
|
|
| 287 |
| 00:21:49,000 --> 00:21:50,000 |
| It has one property. |
|
|
| 288 |
| 00:21:51,000 --> 00:21:58,000 |
| This is property of message type inside the one massive yet name of the thread for our demo purposes |
|
|
| 289 |
| 00:21:58,000 --> 00:21:59,000 |
| to print its name to consult. |
|
|
| 290 |
| 00:22:00,000 --> 00:22:02,000 |
| And after that I have synchronized S.. |
|
|
| 291 |
| 00:22:03,000 --> 00:22:09,000 |
| I didn't make synchronized maps because in this case all reader objects would have separate monitor |
|
|
| 292 |
| 00:22:10,000 --> 00:22:11,000 |
| and need common monitoring. |
|
|
| 293 |
| 00:22:11,000 --> 00:22:13,000 |
| There's a shared between two threats. |
|
|
| 294 |
| 00:22:14,000 --> 00:22:20,000 |
| This is additional advantage of synchronized block because you can pass any object as a reference to |
|
|
| 295 |
| 00:22:20,000 --> 00:22:21,000 |
| capture monitor. |
|
|
| 296 |
| 00:22:22,000 --> 00:22:26,000 |
| And I have this massive object that is shared between two waiters. |
|
|
| 297 |
| 00:22:26,000 --> 00:22:29,000 |
| So I kept your monitor off message object. |
|
|
| 298 |
| 00:22:29,000 --> 00:22:37,000 |
| After that, I claim to cancel and indicate that this threat is waiting to be notified and Prince Current |
|
|
| 299 |
| 00:22:37,000 --> 00:22:41,000 |
| milliseconds after that I go wait Masad on my message object. |
|
|
| 300 |
| 00:22:41,000 --> 00:22:47,000 |
| One more important thing you can call way Massud only in specific context. |
|
|
| 301 |
| 00:22:47,000 --> 00:22:53,000 |
| You can call this method only from synchronized sections and from synchronized methods in case you would |
|
|
| 302 |
| 00:22:53,000 --> 00:22:54,000 |
| invoke weight. |
|
|
| 303 |
| 00:22:54,000 --> 00:23:00,000 |
| Massive note in synchronized context, you will get runtime exception with name, illegal and interstate |
|
|
| 304 |
| 00:23:00,000 --> 00:23:04,000 |
| exception because Red is not an owner of a monitor. |
|
|
| 305 |
| 00:23:05,000 --> 00:23:11,000 |
| Once I call Weight Masset, this thread is in the waiting queue to proceed execution when it will be |
|
|
| 306 |
| 00:23:11,000 --> 00:23:12,000 |
| notified. |
|
|
| 307 |
| 00:23:12,000 --> 00:23:16,000 |
| At the same time, the second reader managed to enter this section. |
|
|
| 308 |
| 00:23:16,000 --> 00:23:23,000 |
| Considering the first reader called Wait Masset on monitor, that means that the monitor is not blocked |
|
|
| 309 |
| 00:23:23,000 --> 00:23:26,000 |
| and another reader can enter the section. |
|
|
| 310 |
| 00:23:26,000 --> 00:23:29,000 |
| Now it is time to learn what is happening next. |
|
|
| 311 |
| 00:23:29,000 --> 00:23:31,000 |
| Let's get back to our demo file. |
|
|
| 312 |
| 00:23:31,000 --> 00:23:34,000 |
| Now it's time to create a notifier object. |
|
|
| 313 |
| 00:23:34,000 --> 00:23:39,000 |
| Notifier type is my custom type that I also described in this package. |
|
|
| 314 |
| 00:23:39,000 --> 00:23:43,000 |
| Pay attention that I pass the reference to the same message object. |
|
|
| 315 |
| 00:23:43,000 --> 00:23:44,000 |
| Great. |
|
|
| 316 |
| 00:23:44,000 --> 00:23:48,000 |
| A threat was named Notifier and started after that. |
|
|
| 317 |
| 00:23:48,000 --> 00:23:49,000 |
| I printed all threads I started. |
|
|
| 318 |
| 00:23:50,000 --> 00:23:52,000 |
| Let's investigate what this notified do. |
|
|
| 319 |
| 00:23:52,000 --> 00:23:58,000 |
| As you can see, objects of this type also will store as a reference to the message object. |
|
|
| 320 |
| 00:23:58,000 --> 00:23:59,000 |
| This is our monitor. |
|
|
| 321 |
| 00:24:00,000 --> 00:24:07,000 |
| In one method we get the name of the threat and indicate that this threat started its work after Z, |
|
|
| 322 |
| 00:24:07,000 --> 00:24:10,000 |
| I made this threat sleep for one hundred milliseconds. |
|
|
| 323 |
| 00:24:10,000 --> 00:24:14,000 |
| This is to ensure that the reader objects captured monitor first. |
|
|
| 324 |
| 00:24:14,000 --> 00:24:22,000 |
| Once the threat wakes up, I try to enter, synchronize the book and undo any other threat is captured |
|
|
| 325 |
| 00:24:22,000 --> 00:24:23,000 |
| in message monitor. |
|
|
| 326 |
| 00:24:23,000 --> 00:24:30,000 |
| All other threats, including this one will stay right before the critical section and would not enter |
|
|
| 327 |
| 00:24:30,000 --> 00:24:34,000 |
| it until get notified from the threats that the monitor is released. |
|
|
| 328 |
| 00:24:34,000 --> 00:24:37,000 |
| You remember that in other threats we invoked. |
|
|
| 329 |
| 00:24:37,000 --> 00:24:38,000 |
| Wait Massett. |
|
|
| 330 |
| 00:24:38,000 --> 00:24:43,000 |
| That means that Notifier may enter this section and capture Monisha. |
|
|
| 331 |
| 00:24:43,000 --> 00:24:45,000 |
| In this critical section. |
|
|
| 332 |
| 00:24:45,000 --> 00:24:47,000 |
| We perform message processing. |
|
|
| 333 |
| 00:24:47,000 --> 00:24:51,000 |
| We change the text to indicate which Notifier updated the message. |
|
|
| 334 |
| 00:24:51,000 --> 00:24:59,000 |
| And after that I invoke is to notify or notify all assets in case I would invoke notify massive on the |
|
|
| 335 |
| 00:24:59,000 --> 00:25:01,000 |
| one threat will be notified. |
|
|
| 336 |
| 00:25:01,000 --> 00:25:03,000 |
| Is a reader one or reader. |
|
|
| 337 |
| 00:25:03,000 --> 00:25:04,000 |
| So let's check this. |
|
|
| 338 |
| 00:25:05,000 --> 00:25:06,000 |
| I run them a file. |
|
|
| 339 |
| 00:25:06,000 --> 00:25:11,000 |
| Here is a notification about we do once read started notify us. |
|
|
| 340 |
| 00:25:11,000 --> 00:25:16,000 |
| Threats started here and we are to start started and waiting to get notified here at this time. |
|
|
| 341 |
| 00:25:17,000 --> 00:25:22,000 |
| And once I called notify MassArt reader finished its execution. |
|
|
| 342 |
| 00:25:22,000 --> 00:25:27,000 |
| So now you can see that we do one, get notified and read other one message. |
|
|
| 343 |
| 00:25:27,000 --> 00:25:30,000 |
| Protest in the source code of reader class. |
|
|
| 344 |
| 00:25:30,000 --> 00:25:36,000 |
| You can see that I print this text to console after wait Macit at the end of round method. |
|
|
| 345 |
| 00:25:36,000 --> 00:25:39,000 |
| So often defecation all code that is below. |
|
|
| 346 |
| 00:25:39,000 --> 00:25:41,000 |
| Wait Massata got executed. |
|
|
| 347 |
| 00:25:41,000 --> 00:25:44,000 |
| Pay attention that our game isn't stopped yet. |
|
|
| 348 |
| 00:25:44,000 --> 00:25:50,000 |
| You can see this red stop sign that tells us that I can stop game but it is run. |
|
|
| 349 |
| 00:25:50,000 --> 00:25:53,000 |
| But why another idle threat is working now. |
|
|
| 350 |
| 00:25:54,000 --> 00:25:56,000 |
| It actually does nothing at the moment. |
|
|
| 351 |
| 00:25:56,000 --> 00:25:59,000 |
| It is just waiting to be notified in this line. |
|
|
| 352 |
| 00:26:00,000 --> 00:26:05,000 |
| But only we know that there are no threats left in the app right now that would be able to notify us |
|
|
| 353 |
| 00:26:05,000 --> 00:26:08,000 |
| with their object all as a threat. |
|
|
| 354 |
| 00:26:08,000 --> 00:26:15,000 |
| I mean, the main threat with the one threat notifier already executed and finished, and this is the |
|
|
| 355 |
| 00:26:15,000 --> 00:26:17,000 |
| last threat that is waiting right now. |
|
|
| 356 |
| 00:26:17,000 --> 00:26:24,000 |
| Let me stop again if you know that such case may happen, in case you know that two more threats might |
|
|
| 357 |
| 00:26:24,000 --> 00:26:30,000 |
| enter a critical section and wait until being notified, you should think about your multiscreen logic |
|
|
| 358 |
| 00:26:30,000 --> 00:26:32,000 |
| very carefully to avoid cases like this. |
|
|
| 359 |
| 00:26:33,000 --> 00:26:37,000 |
| One thread is waiting as low as a threat, always a threat. |
|
|
| 360 |
| 00:26:37,000 --> 00:26:38,000 |
| How to figure this? |
|
|
| 361 |
| 00:26:39,000 --> 00:26:45,000 |
| You should control how many times you call Wakamatsu and how many times you call notify Mass. |
|
|
| 362 |
| 00:26:46,000 --> 00:26:53,000 |
| Considering we have one point in our app where we call notify MassArt in our single Notify Threat and |
|
|
| 363 |
| 00:26:53,000 --> 00:26:55,000 |
| we have to either objects where we call with Macit. |
|
|
| 364 |
| 00:26:56,000 --> 00:27:03,000 |
| Let's invoke notify all Massett in our notify I open, notify a class and will invoke notify all Masset |
|
|
| 365 |
| 00:27:03,000 --> 00:27:05,000 |
| instead simply notify Mass. |
|
|
| 366 |
| 00:27:06,000 --> 00:27:07,000 |
| Let's run our F one more time. |
|
|
| 367 |
| 00:27:08,000 --> 00:27:13,000 |
| Now you can see that all threats finished their work and no other threats running. |
|
|
| 368 |
| 00:27:14,000 --> 00:27:15,000 |
| We have both. |
|
|
| 369 |
| 00:27:15,000 --> 00:27:17,000 |
| Neither one and we are to notify. |
|
|
| 370 |
| 00:27:17,000 --> 00:27:22,000 |
| You can verify this when instigation of console output is clear. |
|
|
| 371 |
| 00:27:22,000 --> 00:27:28,000 |
| It is great that now you know how to work with notified masses and synchronization basics. |
|
|
| 372 |
| 00:27:28,000 --> 00:27:31,000 |
| Let's recap what we have learned in this lesson. |
|
|
| 373 |
| 00:27:31,000 --> 00:27:34,000 |
| In this lesson we learned what critical section is. |
|
|
| 374 |
| 00:27:35,000 --> 00:27:38,000 |
| You understood what atomic and atomic operations are. |
|
|
| 375 |
| 00:27:39,000 --> 00:27:41,000 |
| And we are still going to learn with you. |
|
|
| 376 |
| 00:27:41,000 --> 00:27:45,000 |
| Jabiri two concurrent atomic package in the next lessons. |
|
|
| 377 |
| 00:27:45,000 --> 00:27:46,000 |
| So stay tuned. |
|
|
| 378 |
| 00:27:47,000 --> 00:27:51,000 |
| Now, you know what monitor and mutex are and what is the difference between them? |
|
|
| 379 |
| 00:27:51,000 --> 00:27:56,000 |
| Also, you know what a synchronized method and what a synchronized block. |
|
|
| 380 |
| 00:27:56,000 --> 00:28:01,000 |
| And at the end of the lesson, we have learned what weight notify and notify all methods are. |
|
|
| 381 |
| 00:28:02,000 --> 00:28:05,000 |
| That's all for today, hope you enjoyed this lesson. |
|
|
| 382 |
| 00:28:06,000 --> 00:28:07,000 |
| Thank you for your attention. |
|
|
| 383 |
| 00:28:07,000 --> 00:28:09,000 |
| See you in the next lesson. |
|
|
|
|