java-development-for-beginners-learnit / 27 - Multithreading /005 Memory Management in Multithreading Programs_en.srt
| 1 | |
| 00:00:05,000 --> 00:00:11,000 | |
| Hello, today, we're going to have interesting lesson, you know, sometimes it happens and the topics | |
| 2 | |
| 00:00:11,000 --> 00:00:17,000 | |
| that I need to explain it, but they're either too small for a separate lesson or highly connected with | |
| 3 | |
| 00:00:17,000 --> 00:00:17,000 | |
| other topics. | |
| 4 | |
| 00:00:18,000 --> 00:00:22,000 | |
| That's why a group such topics and decided to put them in one lesson. | |
| 5 | |
| 00:00:22,000 --> 00:00:27,000 | |
| We'll start from understanding of memory management in Java and just writing programs. | |
| 6 | |
| 00:00:27,000 --> 00:00:32,000 | |
| This will give you information about how data is managed by different threats. | |
| 7 | |
| 00:00:32,000 --> 00:00:36,000 | |
| It is also important to understand hardware, memory, architecture. | |
| 8 | |
| 00:00:36,000 --> 00:00:42,000 | |
| It is a different from general memory model, but your memory model works with hardware memory and is | |
| 9 | |
| 00:00:42,000 --> 00:00:43,000 | |
| built on top of it. | |
| 10 | |
| 00:00:44,000 --> 00:00:50,000 | |
| That's why software engineers, we need to understand how all this is connected, learns this information. | |
| 11 | |
| 00:00:50,000 --> 00:00:56,000 | |
| It will be easier for you to understand volatile keywords and how it works in various lessons. | |
| 12 | |
| 00:00:56,000 --> 00:01:01,000 | |
| We already talked about atomic operations and I mentioned that there are generally two concurrent atomic | |
| 13 | |
| 00:01:01,000 --> 00:01:05,000 | |
| package that contains types that supports atomic operations. | |
| 14 | |
| 00:01:05,000 --> 00:01:11,000 | |
| In this letter, we'll review this package at the end of the and will want to read local variables are. | |
| 15 | |
| 00:01:12,000 --> 00:01:17,000 | |
| I will also share with you some use cases when you might need to use read local, but it will be up | |
| 16 | |
| 00:01:17,000 --> 00:01:22,000 | |
| to you how to use this to also talk about inheritable local. | |
| 17 | |
| 00:01:22,000 --> 00:01:24,000 | |
| And I will show you examples. | |
| 18 | |
| 00:01:24,000 --> 00:01:25,000 | |
| Let's start. | |
| 19 | |
| 00:01:25,000 --> 00:01:31,000 | |
| And before we start learning to read local, volatile and other concepts, let's understand first memory | |
| 20 | |
| 00:01:31,000 --> 00:01:37,000 | |
| management and how Seurat's use in memory, why it is important for us, because we need to know and | |
| 21 | |
| 00:01:37,000 --> 00:01:43,000 | |
| understand when different threads can use values, return to shared variables by Osas threats and how | |
| 22 | |
| 00:01:43,000 --> 00:01:46,000 | |
| to synchronize access to shared variables when necessary. | |
| 23 | |
| 00:01:46,000 --> 00:01:52,000 | |
| When I have multiple threats, Dunam divides memories between stress tests and the hit their separate | |
| 24 | |
| 00:01:52,000 --> 00:01:53,000 | |
| stack for each threat. | |
| 25 | |
| 00:01:53,000 --> 00:01:55,000 | |
| And you can see the visualizations a slide. | |
| 26 | |
| 00:01:55,000 --> 00:01:57,000 | |
| What is stored in threat stack? | |
| 27 | |
| 00:01:58,000 --> 00:02:03,000 | |
| If you remember less lesson about a memory module from my Java course, you might guess what is stored | |
| 28 | |
| 00:02:03,000 --> 00:02:09,000 | |
| in old stack of each threat is information about mass that we invoke from the threat or local variables | |
| 29 | |
| 00:02:09,000 --> 00:02:11,000 | |
| for each must have been executed. | |
| 30 | |
| 00:02:12,000 --> 00:02:16,000 | |
| Local variables created in the threat obviously are not visible to all of us. | |
| 31 | |
| 00:02:16,000 --> 00:02:22,000 | |
| Let's hope you remember that if memory stores, objects, objects are instances of all reference types | |
| 32 | |
| 00:02:22,000 --> 00:02:23,000 | |
| that we know. | |
| 33 | |
| 00:02:23,000 --> 00:02:29,000 | |
| And it doesn't matter if an object was created as a threat and assigned to a local variable, or even | |
| 34 | |
| 00:02:29,000 --> 00:02:35,000 | |
| if it is created as a member variable of another object, the object is still stored in the hip, but | |
| 35 | |
| 00:02:35,000 --> 00:02:39,000 | |
| the references to these objects are stored in threads stack. | |
| 36 | |
| 00:02:40,000 --> 00:02:43,000 | |
| Let's look at more detailed version of previous life here. | |
| 37 | |
| 00:02:43,000 --> 00:02:48,000 | |
| You can see where information about local variables and objects is stored. | |
| 38 | |
| 00:02:48,000 --> 00:02:49,000 | |
| So nothing new to you. | |
| 39 | |
| 00:02:49,000 --> 00:02:52,000 | |
| In case you are familiar with Java memory module. | |
| 40 | |
| 00:02:52,000 --> 00:02:58,000 | |
| Also important thing to highlight here that the variable may be of primitive and reference type variable | |
| 41 | |
| 00:02:58,000 --> 00:03:05,000 | |
| of primitive type contains value in itself and completely stored in threat stack in case variable has | |
| 42 | |
| 00:03:05,000 --> 00:03:06,000 | |
| reference time. | |
| 43 | |
| 00:03:06,000 --> 00:03:13,000 | |
| In this case, a reference to the heap is stored in stack memory and object is stored in the memory. | |
| 44 | |
| 00:03:13,000 --> 00:03:15,000 | |
| What about static variables? | |
| 45 | |
| 00:03:15,000 --> 00:03:20,000 | |
| Take into account static variables don't belong to any object, but belong to class itself. | |
| 46 | |
| 00:03:21,000 --> 00:03:24,000 | |
| They are stored in the memory along with the class definition. | |
| 47 | |
| 00:03:25,000 --> 00:03:31,000 | |
| Since Case Thread has a reference to an object, it can access object in memory using the reference | |
| 48 | |
| 00:03:31,000 --> 00:03:35,000 | |
| and each side may do this in case it knows is a reference to an object. | |
| 49 | |
| 00:03:36,000 --> 00:03:38,000 | |
| And now let me share a really interesting scene. | |
| 50 | |
| 00:03:39,000 --> 00:03:43,000 | |
| Imagine that this column masset on the same object at the same moment of time. | |
| 51 | |
| 00:03:44,000 --> 00:03:48,000 | |
| These threats, both of them will access objects, variables. | |
| 52 | |
| 00:03:48,000 --> 00:03:53,000 | |
| But we have just learned the local variables are stored in a stack of each threat. | |
| 53 | |
| 00:03:53,000 --> 00:04:00,000 | |
| So each threat will have its own reference to the object in the Heat and its own copy of the local variable | |
| 54 | |
| 00:04:01,000 --> 00:04:05,000 | |
| that is important for understanding, for data manipulation from different threats. | |
| 55 | |
| 00:04:05,000 --> 00:04:12,000 | |
| So in this case, some local variables are completely copied to each threat, and each threat has copy | |
| 56 | |
| 00:04:12,000 --> 00:04:14,000 | |
| of the reference to an object in memory. | |
| 57 | |
| 00:04:15,000 --> 00:04:18,000 | |
| Now let's talk about hardware, memory architecture. | |
| 58 | |
| 00:04:18,000 --> 00:04:24,000 | |
| As I already mentioned in the agenda of this lesson, it is important for us to understand how hardware | |
| 59 | |
| 00:04:24,000 --> 00:04:28,000 | |
| memory is architected because general memory model is built on top of it. | |
| 60 | |
| 00:04:29,000 --> 00:04:33,000 | |
| So another computer often has to and even more in central processing units. | |
| 61 | |
| 00:04:34,000 --> 00:04:36,000 | |
| That is why they're called CPU. | |
| 62 | |
| 00:04:37,000 --> 00:04:38,000 | |
| What does this mean for us? | |
| 63 | |
| 00:04:38,000 --> 00:04:46,000 | |
| That means that we can physically has calculations done in parallel because you can run the one thread | |
| 64 | |
| 00:04:46,000 --> 00:04:47,000 | |
| at any given time. | |
| 65 | |
| 00:04:48,000 --> 00:04:54,000 | |
| C.P.U contains a set of registers zis registers consider to be memory of our CPU. | |
| 66 | |
| 00:04:54,000 --> 00:05:01,000 | |
| That's why you can perform operations on these registers much faster, that it can perform on variables | |
| 67 | |
| 00:05:01,000 --> 00:05:02,000 | |
| in the main memory. | |
| 68 | |
| 00:05:02,000 --> 00:05:07,000 | |
| Besides registers, CPU also have Sibiu cash memory. | |
| 69 | |
| 00:05:07,000 --> 00:05:13,000 | |
| And again, if we were talking about performance, it's worth to say that C.P.U is able to access cash | |
| 70 | |
| 00:05:13,000 --> 00:05:20,000 | |
| memory much faster than the RAM memory, but obviously not as fast as it can access internal registers. | |
| 71 | |
| 00:05:21,000 --> 00:05:24,000 | |
| ROMME stands for random access memory. | |
| 72 | |
| 00:05:24,000 --> 00:05:31,000 | |
| It is a form of computer memory that can be read and changed in any order typically used to store data. | |
| 73 | |
| 00:05:32,000 --> 00:05:37,000 | |
| For example, you start from some room is reserved for Google. | |
| 74 | |
| 00:05:37,000 --> 00:05:42,000 | |
| You start your Java app JVM reserves from memory for the Java process. | |
| 75 | |
| 00:05:43,000 --> 00:05:50,000 | |
| LCP use may access around and the RAM is typically much bigger than the cache memory of the CPU's. | |
| 76 | |
| 00:05:50,000 --> 00:05:54,000 | |
| Let's understand how the process of reading and writing data is happening. | |
| 77 | |
| 00:05:54,000 --> 00:06:00,000 | |
| In case you need to read some data from RAM, it will read some parts of the data from RAM into the | |
| 78 | |
| 00:06:00,000 --> 00:06:07,000 | |
| CPU cache and it is also possible the CPU will read some parts of the data into internal registers and | |
| 79 | |
| 00:06:07,000 --> 00:06:10,000 | |
| only after that operate on that data. | |
| 80 | |
| 00:06:10,000 --> 00:06:13,000 | |
| And in case you need to write, result back to RAM. | |
| 81 | |
| 00:06:14,000 --> 00:06:17,000 | |
| We are going through the same route, but just in other direction. | |
| 82 | |
| 00:06:18,000 --> 00:06:25,000 | |
| From CPU registers to RAM, CPU will flush the result of computation from its internal register. | |
| 83 | |
| 00:06:25,000 --> 00:06:32,000 | |
| Those are cache memory and at some point the value back to the RAM eviction policy from CPU cash is | |
| 84 | |
| 00:06:32,000 --> 00:06:33,000 | |
| simple. | |
| 85 | |
| 00:06:33,000 --> 00:06:38,000 | |
| One memory is needed for something else, then cache memory is flashed back to zero. | |
| 86 | |
| 00:06:39,000 --> 00:06:45,000 | |
| So as you can see, Java memory model and hardware memory architecture are not the same sync. | |
| 87 | |
| 00:06:45,000 --> 00:06:52,000 | |
| There is no separation between stack and heap in hardware memory, but how it is connected. | |
| 88 | |
| 00:06:52,000 --> 00:07:00,000 | |
| Then let me show on the next slide both stack and the heap memory allocated in ram memory that is reserved | |
| 89 | |
| 00:07:00,000 --> 00:07:08,000 | |
| for Java process parts of threats stacks and he may sometimes be present in CPU caches and in internal | |
| 90 | |
| 00:07:08,000 --> 00:07:09,000 | |
| SEPI registers. | |
| 91 | |
| 00:07:09,000 --> 00:07:16,000 | |
| What problem may occur in case objects and variables are stored in different memory areas in the computer? | |
| 92 | |
| 00:07:17,000 --> 00:07:18,000 | |
| The domain potential problems. | |
| 93 | |
| 00:07:19,000 --> 00:07:25,000 | |
| There was a batch of threat updates and the second problem is there is a condition during the reading, | |
| 94 | |
| 00:07:25,000 --> 00:07:27,000 | |
| checking and writing shared variables. | |
| 95 | |
| 00:07:28,000 --> 00:07:31,000 | |
| Let me explain what these issues are about and details. | |
| 96 | |
| 00:07:32,000 --> 00:07:34,000 | |
| The first issue is visibility of threat updates. | |
| 97 | |
| 00:07:35,000 --> 00:07:38,000 | |
| Imagine that some updated copy of the variable. | |
| 98 | |
| 00:07:38,000 --> 00:07:45,000 | |
| There is no guarantees that other threats will be able to see this update in case the threats has the | |
| 99 | |
| 00:07:45,000 --> 00:07:46,000 | |
| reference to the same object. | |
| 100 | |
| 00:07:46,000 --> 00:07:50,000 | |
| Without using proper synchronization or volatile keyword. | |
| 101 | |
| 00:07:51,000 --> 00:07:58,000 | |
| There is a chance that updates to the shared object made by one threat may not be visible to NSW. | |
| 102 | |
| 00:07:58,000 --> 00:07:59,000 | |
| How it may happen. | |
| 103 | |
| 00:08:00,000 --> 00:08:01,000 | |
| Let's imagine the next case. | |
| 104 | |
| 00:08:01,000 --> 00:08:08,000 | |
| Initially shared object is stored in RAM memory main memory and imagine the one thread that is running | |
| 105 | |
| 00:08:08,000 --> 00:08:10,000 | |
| on CPU object in the state of this object. | |
| 106 | |
| 00:08:11,000 --> 00:08:17,000 | |
| As long as a cache has not been flashed back to the main memory, the updated version of the shared | |
| 107 | |
| 00:08:17,000 --> 00:08:22,000 | |
| object is not visible to run on other CPU's. | |
| 108 | |
| 00:08:22,000 --> 00:08:23,000 | |
| Is that clear? | |
| 109 | |
| 00:08:24,000 --> 00:08:31,000 | |
| This may end up that each thread contains its own version of the same variable in different CPU cache | |
| 110 | |
| 00:08:31,000 --> 00:08:32,000 | |
| as slide. | |
| 111 | |
| 00:08:32,000 --> 00:08:39,000 | |
| You can see how to threats update the same account variable and until CPU cache memory isn't flashed, | |
| 112 | |
| 00:08:39,000 --> 00:08:43,000 | |
| these updates are sitting there to solve this issue. | |
| 113 | |
| 00:08:43,000 --> 00:08:45,000 | |
| We may use volatile keyword. | |
| 114 | |
| 00:08:46,000 --> 00:08:49,000 | |
| I will explain later what volatile keyword does. | |
| 115 | |
| 00:08:50,000 --> 00:08:52,000 | |
| Let's discuss the second issue race conditions. | |
| 116 | |
| 00:08:53,000 --> 00:08:59,000 | |
| Imagine that you have a variable account of a shared object, this variable and CPU cache of one threat | |
| 117 | |
| 00:08:59,000 --> 00:09:01,000 | |
| and in CPU a cache of another threat. | |
| 118 | |
| 00:09:02,000 --> 00:09:06,000 | |
| Both threats does the same thing they add the one does account. | |
| 119 | |
| 00:09:06,000 --> 00:09:14,000 | |
| Variable count has been incremented two times and then this program would run sequentially and each | |
| 120 | |
| 00:09:14,000 --> 00:09:16,000 | |
| threat update is a verbal one after another. | |
| 121 | |
| 00:09:16,000 --> 00:09:19,000 | |
| In this case, the value of Cowens variable would be true. | |
| 122 | |
| 00:09:20,000 --> 00:09:22,000 | |
| However, this is not the case. | |
| 123 | |
| 00:09:22,000 --> 00:09:30,000 | |
| The increments happened concurrently and we got last update because no matter which threat update version | |
| 124 | |
| 00:09:30,000 --> 00:09:36,000 | |
| of counts variable in main memory is updated, value will be overridden by another threat. | |
| 125 | |
| 00:09:36,000 --> 00:09:39,000 | |
| How to solve this synchronize blocks. | |
| 126 | |
| 00:09:39,000 --> 00:09:45,000 | |
| In this course you will learn how to use synchronize blocks properly to synchronize access of multiple | |
| 127 | |
| 00:09:45,000 --> 00:09:47,000 | |
| threats to critical sections. | |
| 128 | |
| 00:09:47,000 --> 00:09:53,000 | |
| I believe that now you understand how memory management is performed on different levels of the threat | |
| 129 | |
| 00:09:53,000 --> 00:09:54,000 | |
| in programs. | |
| 130 | |
| 00:09:54,000 --> 00:09:59,000 | |
| I promise you also to explain what volatile keywords is and how it works. | |
| 131 | |
| 00:09:59,000 --> 00:10:02,000 | |
| As you already can understand that Dune's and. | |
| 132 | |
| 00:10:02,000 --> 00:10:10,000 | |
| We should consider a lot of other things the process in flush its cash buffer in any order dude compiler | |
| 133 | |
| 00:10:10,000 --> 00:10:11,000 | |
| may optimize our execution. | |
| 134 | |
| 00:10:11,000 --> 00:10:17,000 | |
| We are ordering order and is an optimization technique for performance improvements. | |
| 135 | |
| 00:10:17,000 --> 00:10:23,000 | |
| When you write the program, you expect instructions will be executed in order as written in the program. | |
| 136 | |
| 00:10:23,000 --> 00:10:25,000 | |
| But that is not always the case. | |
| 137 | |
| 00:10:25,000 --> 00:10:33,000 | |
| For example, you may declare two fields in time that is equal to 10 and JS that is equal to five. | |
| 138 | |
| 00:10:33,000 --> 00:10:34,000 | |
| It might happen. | |
| 139 | |
| 00:10:34,000 --> 00:10:42,000 | |
| That variable is the second one in zero will be initialized first, but I variable still wouldn't be | |
| 140 | |
| 00:10:42,000 --> 00:10:51,000 | |
| initialized and has the zero value, but not then because zero is a default value for I so far. | |
| 141 | |
| 00:10:51,000 --> 00:10:58,000 | |
| Non-dependent operations like initialization of course fields in some case compiler may apply some optimizations | |
| 142 | |
| 00:10:58,000 --> 00:11:01,000 | |
| and the ordering is one of such techniques. | |
| 143 | |
| 00:11:01,000 --> 00:11:08,000 | |
| And in case I will use volatile keywords with the fields, this will be assigned for runtime environment | |
| 144 | |
| 00:11:08,000 --> 00:11:11,000 | |
| that I need predictable order for operations. | |
| 145 | |
| 00:11:11,000 --> 00:11:15,000 | |
| With these variables, orderings won't be applied to such variables. | |
| 146 | |
| 00:11:15,000 --> 00:11:22,000 | |
| And also I need to flash any updates to these variables instantly to make updates visible to all other | |
| 147 | |
| 00:11:22,000 --> 00:11:22,000 | |
| threats. | |
| 148 | |
| 00:11:22,000 --> 00:11:27,000 | |
| Does it make sense to explain how volatile works and why do we need it? | |
| 149 | |
| 00:11:27,000 --> 00:11:34,000 | |
| I had to explain your hardware, memory architecture and Java memory model, but now I believe it is | |
| 150 | |
| 00:11:34,000 --> 00:11:38,000 | |
| crystal clear what problem we are trying to solve by adding volatile keywords. | |
| 151 | |
| 00:11:38,000 --> 00:11:45,000 | |
| And now when I break, huge means that you would find in the Internet and in volatile Keever, it doesn't | |
| 152 | |
| 00:11:45,000 --> 00:11:49,000 | |
| mean that all operations with such variable will be atomic. | |
| 153 | |
| 00:11:50,000 --> 00:11:57,000 | |
| You may find statements in Internet and sometimes even on stack overflow that volatile variables behave | |
| 154 | |
| 00:11:57,000 --> 00:11:59,000 | |
| like atomic and operations. | |
| 155 | |
| 00:11:59,000 --> 00:12:00,000 | |
| That is not true. | |
| 156 | |
| 00:12:01,000 --> 00:12:06,000 | |
| The effect of volatile keywords is that approximately each individual read or write. | |
| 157 | |
| 00:12:06,000 --> 00:12:11,000 | |
| A separation on that variable is made atomically visible to all threads. | |
| 158 | |
| 00:12:12,000 --> 00:12:14,000 | |
| However, operations is. | |
| 159 | |
| 00:12:14,000 --> 00:12:21,000 | |
| It requires more than one redivide cycle, such as incremented, for example, will not be executed | |
| 160 | |
| 00:12:21,000 --> 00:12:29,000 | |
| as atomic because we need read value of the variable at one safe result of calculation and assign that | |
| 161 | |
| 00:12:29,000 --> 00:12:35,000 | |
| this variable Z separation's one V atomic, even if you will work with volatile variable. | |
| 162 | |
| 00:12:36,000 --> 00:12:42,000 | |
| Remember that only atomic operations I Stipe's from Java to concurrent atomic package. | |
| 163 | |
| 00:12:43,000 --> 00:12:46,000 | |
| We talked about these atomic types for a long time already. | |
| 164 | |
| 00:12:47,000 --> 00:12:51,000 | |
| Let me show them how to work with these types, first of all. | |
| 165 | |
| 00:12:51,000 --> 00:12:57,000 | |
| And as always, I recommended to start from the official documentation from Oracle, from documentation. | |
| 166 | |
| 00:12:57,000 --> 00:13:04,000 | |
| We see that this package is a small tool kit of classes that support locally safe programming on single | |
| 167 | |
| 00:13:04,000 --> 00:13:04,000 | |
| variables. | |
| 168 | |
| 00:13:05,000 --> 00:13:07,000 | |
| Here you can find class summary. | |
| 169 | |
| 00:13:08,000 --> 00:13:13,000 | |
| It is easy to remember these class names because most of them have atomic at the beginning. | |
| 170 | |
| 00:13:14,000 --> 00:13:17,000 | |
| Atomic Boulin Atomic Integer atomic bomb. | |
| 171 | |
| 00:13:17,000 --> 00:13:21,000 | |
| I bet you can understand what type of values these atomic types. | |
| 172 | |
| 00:13:21,000 --> 00:13:28,000 | |
| Berquist Atomic Reference is a type that describes an object reference that may be updated atomically. | |
| 173 | |
| 00:13:29,000 --> 00:13:34,000 | |
| Each of these types provide its own API to perform necessary operations. | |
| 174 | |
| 00:13:34,000 --> 00:13:41,000 | |
| Also that types to execute threats, safe operations with arrays, atomic integer array, atomic clock | |
| 175 | |
| 00:13:41,000 --> 00:13:49,000 | |
| array, atomic reference and the even more times, for example, double atter, you can use this type | |
| 176 | |
| 00:13:49,000 --> 00:13:49,000 | |
| to perform. | |
| 177 | |
| 00:13:49,000 --> 00:13:51,000 | |
| Swed safe addition of double's. | |
| 178 | |
| 00:13:52,000 --> 00:13:56,000 | |
| Let's jump to the code examples and I'll show you how to work with the Stipe's. | |
| 179 | |
| 00:13:57,000 --> 00:14:03,000 | |
| For example, here is a code that creates 10000 threats and update counter variable Baycol increment | |
| 180 | |
| 00:14:03,000 --> 00:14:05,000 | |
| massive protection. | |
| 181 | |
| 00:14:05,000 --> 00:14:11,000 | |
| That increment method is not a synchronized one and they also don't have any synchronized blocks here. | |
| 182 | |
| 00:14:11,000 --> 00:14:16,000 | |
| But this code is safe and the security from animal to certain issues. | |
| 183 | |
| 00:14:17,000 --> 00:14:17,000 | |
| Why? | |
| 184 | |
| 00:14:18,000 --> 00:14:25,000 | |
| Because my counter has type atomic integer that supports safe operations in increments. | |
| 185 | |
| 00:14:25,000 --> 00:14:32,000 | |
| Masset, I use API of atomic integer done in case and is incremental value I can use is I get an increment | |
| 186 | |
| 00:14:32,000 --> 00:14:35,000 | |
| or increment and get these. | |
| 187 | |
| 00:14:35,000 --> 00:14:43,000 | |
| Tomas's are logically difference in terms of what value you want to get before or after an increment. | |
| 188 | |
| 00:14:43,000 --> 00:14:48,000 | |
| Let's run this example and in console you will always find ten thousand. | |
| 189 | |
| 00:14:48,000 --> 00:14:54,000 | |
| That is because during increment operation as a threat, we're not able to update the counter variable | |
| 190 | |
| 00:14:54,000 --> 00:14:55,000 | |
| in parallel. | |
| 191 | |
| 00:14:55,000 --> 00:14:57,000 | |
| Let me open the source code of this time. | |
| 192 | |
| 00:14:58,000 --> 00:15:02,000 | |
| If you look at S1, you would find that the. | |
| 193 | |
| 00:15:02,000 --> 00:15:10,000 | |
| Plenty of useful assets, some of them are get and set masses get and add as a single operation if you | |
| 194 | |
| 00:15:10,000 --> 00:15:18,000 | |
| want to, some integer values also their atomic decrements, decrements and get and get in command and | |
| 195 | |
| 00:15:18,000 --> 00:15:22,000 | |
| the masses to convert atomic integer to as a primitive times. | |
| 196 | |
| 00:15:22,000 --> 00:15:26,000 | |
| The rest of the atomic rubber stamps work pretty similar. | |
| 197 | |
| 00:15:26,000 --> 00:15:31,000 | |
| And as always, in case of any questions, feel free to leave your question and comments below this | |
| 198 | |
| 00:15:31,000 --> 00:15:32,000 | |
| here. | |
| 199 | |
| 00:15:32,000 --> 00:15:34,000 | |
| And the last but not the least. | |
| 200 | |
| 00:15:34,000 --> 00:15:37,000 | |
| What I'd like to share with you for today is a thread local. | |
| 201 | |
| 00:15:37,000 --> 00:15:40,000 | |
| I have separate file was named for local demo. | |
| 202 | |
| 00:15:40,000 --> 00:15:45,000 | |
| But before we jump to an example, let's understand a little bit more about Fred. | |
| 203 | |
| 00:15:45,000 --> 00:15:46,000 | |
| Local time. | |
| 204 | |
| 00:15:47,000 --> 00:15:50,000 | |
| So local is a tribe that is declared in Java land package. | |
| 205 | |
| 00:15:51,000 --> 00:15:55,000 | |
| That means you don't need any additional income statements to start using. | |
| 206 | |
| 00:15:55,000 --> 00:16:02,000 | |
| This type of local allows us to store data that will be accessible only by a single one. | |
| 207 | |
| 00:16:02,000 --> 00:16:03,000 | |
| You might need this. | |
| 208 | |
| 00:16:03,000 --> 00:16:09,000 | |
| There might be cases where you don't want the threats, interact with the data of other threats and | |
| 209 | |
| 00:16:09,000 --> 00:16:17,000 | |
| adjusted the variables of local type differ from their normal counterparts in that each thread that | |
| 210 | |
| 00:16:17,000 --> 00:16:23,000 | |
| accesses one has its own independently initialized copy of the variable spread. | |
| 211 | |
| 00:16:23,000 --> 00:16:29,000 | |
| Local instances are typically private static fields and classes that we often associate state with a | |
| 212 | |
| 00:16:29,000 --> 00:16:35,000 | |
| threat, for example, a user, a yi or transactionally, something very specific to one single threat. | |
| 213 | |
| 00:16:36,000 --> 00:16:38,000 | |
| Now let's start with the practical part. | |
| 214 | |
| 00:16:38,000 --> 00:16:41,000 | |
| I declare a private static field of threat. | |
| 215 | |
| 00:16:41,000 --> 00:16:49,000 | |
| Local type parametrized by string threat local will be similar to wrapper you get and set object of | |
| 216 | |
| 00:16:49,000 --> 00:16:51,000 | |
| parametrized type into it. | |
| 217 | |
| 00:16:51,000 --> 00:16:57,000 | |
| You can just create an instance of certain local types like you usually do with all of the reference | |
| 218 | |
| 00:16:57,000 --> 00:16:57,000 | |
| types. | |
| 219 | |
| 00:16:57,000 --> 00:17:04,000 | |
| With the help of your keywords, you can also use static Masset with initial zaftig supplier as method | |
| 220 | |
| 00:17:04,000 --> 00:17:07,000 | |
| argument to initialize the variable. | |
| 221 | |
| 00:17:07,000 --> 00:17:12,000 | |
| If you're not familiar with lambda expressions and supplier type, I recommend it to pass my functional | |
| 222 | |
| 00:17:12,000 --> 00:17:14,000 | |
| programming course for Java engineers. | |
| 223 | |
| 00:17:15,000 --> 00:17:21,000 | |
| There are a lot of examples that will explain the topic of lambda expressions and functional interfaces. | |
| 224 | |
| 00:17:21,000 --> 00:17:27,000 | |
| Let's move on for the sake of the demo and to make it as simple as possible, I will keep my thread | |
| 225 | |
| 00:17:27,000 --> 00:17:32,000 | |
| local parametrized by integer type and I will create object with new keyword. | |
| 226 | |
| 00:17:33,000 --> 00:17:35,000 | |
| After that I implement Runnable interface. | |
| 227 | |
| 00:17:35,000 --> 00:17:41,000 | |
| In this time, in run unmastered, I set random value from zero to one hundred does a transaction I | |
| 228 | |
| 00:17:42,000 --> 00:17:43,000 | |
| with the local variable. | |
| 229 | |
| 00:17:43,000 --> 00:17:46,000 | |
| After that I made my sleep for one second. | |
| 230 | |
| 00:17:47,000 --> 00:17:49,000 | |
| I am doing this for the sake of the demo. | |
| 231 | |
| 00:17:49,000 --> 00:17:56,000 | |
| During one second we can guarantee that both threads will be started and it is one hundred percent assurance | |
| 232 | |
| 00:17:56,000 --> 00:17:59,000 | |
| that this set method will be involved in one. | |
| 233 | |
| 00:18:00,000 --> 00:18:03,000 | |
| And then as a threat, I have to sleep in one second. | |
| 234 | |
| 00:18:03,000 --> 00:18:07,000 | |
| I print the value of thread local to cancel all threads. | |
| 235 | |
| 00:18:07,000 --> 00:18:12,000 | |
| Technically, I need to create threads, objects and start them and pay attention. | |
| 236 | |
| 00:18:12,000 --> 00:18:19,000 | |
| Transaction ID is a static variable and we may assume that it exists in single copy, but both threads | |
| 237 | |
| 00:18:19,000 --> 00:18:22,000 | |
| will have different values associated with this variable. | |
| 238 | |
| 00:18:23,000 --> 00:18:24,000 | |
| Don't believe me. | |
| 239 | |
| 00:18:24,000 --> 00:18:27,000 | |
| Let's run the program after one second pause. | |
| 240 | |
| 00:18:27,000 --> 00:18:28,000 | |
| I see. | |
| 241 | |
| 00:18:28,000 --> 00:18:32,000 | |
| And so the two threads print printed different values of the same static variable. | |
| 242 | |
| 00:18:33,000 --> 00:18:39,000 | |
| How this has happened, you can imagine the thread local is a map in this map. | |
| 243 | |
| 00:18:39,000 --> 00:18:45,000 | |
| This thread is a key and the value is the values that we set our thread local variable. | |
| 244 | |
| 00:18:45,000 --> 00:18:50,000 | |
| And when I get value, I just extract that using the key mussarat object. | |
| 245 | |
| 00:18:51,000 --> 00:18:52,000 | |
| That's why you shouldn't. | |
| 246 | |
| 00:18:52,000 --> 00:18:55,000 | |
| Or is it another stretchable access value from another thread? | |
| 247 | |
| 00:18:56,000 --> 00:19:00,000 | |
| And that values that you said in one thread will be our written in other thread. | |
| 248 | |
| 00:19:01,000 --> 00:19:03,000 | |
| And one more thing related to thread local. | |
| 249 | |
| 00:19:03,000 --> 00:19:06,000 | |
| We have another type that extends throughout local. | |
| 250 | |
| 00:19:06,000 --> 00:19:08,000 | |
| It is inheritable Sareb local. | |
| 251 | |
| 00:19:09,000 --> 00:19:10,000 | |
| What is the difference? | |
| 252 | |
| 00:19:10,000 --> 00:19:17,000 | |
| Instead of each thread having its own value inside the local is inheritable spread local grants, access | |
| 253 | |
| 00:19:17,000 --> 00:19:22,000 | |
| to RELISTOR threat and all child threats created by the threat. | |
| 254 | |
| 00:19:22,000 --> 00:19:25,000 | |
| Let's look at the example I have read local variable. | |
| 255 | |
| 00:19:26,000 --> 00:19:28,000 | |
| This is parametrized by type string. | |
| 256 | |
| 00:19:28,000 --> 00:19:30,000 | |
| Nothing special here. | |
| 257 | |
| 00:19:30,000 --> 00:19:33,000 | |
| And the next field has inheritable spread local time. | |
| 258 | |
| 00:19:34,000 --> 00:19:36,000 | |
| I create the instance of this type with the help of you. | |
| 259 | |
| 00:19:36,000 --> 00:19:40,000 | |
| Keeva, let's run this app and look at the main message. | |
| 260 | |
| 00:19:40,000 --> 00:19:47,000 | |
| Now, I read the first thread and I said the local value and inheritable spread local value. | |
| 261 | |
| 00:19:47,000 --> 00:19:51,000 | |
| After that, I print values that are stored inside these two variables. | |
| 262 | |
| 00:19:52,000 --> 00:19:56,000 | |
| And as you can see in console, everything is straightforward here. | |
| 263 | |
| 00:19:56,000 --> 00:19:59,000 | |
| I can see value of the variables after that. | |
| 264 | |
| 00:19:59,000 --> 00:20:01,000 | |
| Inside this threat, I create a large. | |
| 265 | |
| 00:20:01,000 --> 00:20:08,000 | |
| A threat, this threat is a child's threat and the values of state, local and inheritable threat, | |
| 266 | |
| 00:20:08,000 --> 00:20:14,000 | |
| local variables here and in Arkansas, you can see that I don't have access to the threat local variable | |
| 267 | |
| 00:20:14,000 --> 00:20:17,000 | |
| on this level, but I can see inheritable threat, local value. | |
| 268 | |
| 00:20:17,000 --> 00:20:21,000 | |
| And after that, I create a separate threat threat. | |
| 269 | |
| 00:20:21,000 --> 00:20:24,000 | |
| Number two, I make it sleep for one second. | |
| 270 | |
| 00:20:24,000 --> 00:20:29,000 | |
| And after that, I want to bring the values of threat local and inheritable threat local. | |
| 271 | |
| 00:20:30,000 --> 00:20:36,000 | |
| And as you may already understand, the threat of local law, inheritable threat local is accessible | |
| 272 | |
| 00:20:36,000 --> 00:20:37,000 | |
| from a national threat. | |
| 273 | |
| 00:20:37,000 --> 00:20:39,000 | |
| Hope that this example is clear for you. | |
| 274 | |
| 00:20:39,000 --> 00:20:43,000 | |
| And you know what a threat to local and what is inheritable threat local. | |
| 275 | |
| 00:20:44,000 --> 00:20:46,000 | |
| Let's review what we have learned in this lesson. | |
| 276 | |
| 00:20:46,000 --> 00:20:50,000 | |
| In this lesson, we learned how memory is managed in most training programs. | |
| 277 | |
| 00:20:51,000 --> 00:20:56,000 | |
| Also now, you know, hardware, memory, architecture and how German memory model uses memory. | |
| 278 | |
| 00:20:57,000 --> 00:21:01,000 | |
| All this let us understand whether volatile keyword and why we needed. | |
| 279 | |
| 00:21:02,000 --> 00:21:09,000 | |
| After that, we performed over of two concurrent atomic package and so atomic integer example. | |
| 280 | |
| 00:21:09,000 --> 00:21:14,000 | |
| And at the end of the lesson we learned to read local type and inheritable are local. | |
| 281 | |
| 00:21:15,000 --> 00:21:16,000 | |
| That's it for this lesson. | |
| 282 | |
| 00:21:16,000 --> 00:21:18,000 | |
| Thanks a lot for your attention. | |
| 283 | |
| 00:21:18,000 --> 00:21:21,000 | |
| Have a great day and see you in the next lesson. | |