Thread Synchronization in C# .Net made easy! | Lock | Monitor | Mutex | Semaphore

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hi friends welcome to new video of code Allegiant in this video we will see thread synchronization methods used in c-sharp dotnet so in C shape dotnet there are multiple ways we can synchronize the threads so these are the topics which we'll be covering in this video that is lock monitor manual reset event auto reset event mutex and semaphore so let's see what exactly is lock so I am in Visual Studio and this is a default view which you get when you create a console application so in the main main method I will try to create multiple threads first so I will use a for loop and I will create five threads so to crease start thread I need to have some method so first I will create a public static void some do work method which simulates some long-running work so in the real time application there will be some method which is going to do a long work so in this what we will do is we will just print console dot write line and we'll say thread and the number which we will get is from the thread dot current thread dot manage thread ID so this is a unique identification number which is assigned to every thread by the CLR so we will say thread this number starting and then we will simulate a work by doing a thread dot sleep maybe we will sleep for around two seconds and then I will just copy paste this code and I will change the content as completed so now we will see a log saying thread the number starting and then we will sleep for two seconds and then we will see thread so-and-so completed so now let's start let's start a thread so I'll say thread new thread and I'll pass do work method here and say start so this will start five threads one after the other and at the end here I will say console dot read key so that my console in doesn't get closed automatically after the execution so now let's see what happens when we execute this so in the output you will see that all the five threads started together and all the five threads completed so this is how actually a multi-threading works but now you want to synchronize these threads so that means this part of the code is some special code which you don't want all the thread to access at a time so normally in you call this type of code as critical section so it will be a file reading or writing or think process or network related process and you don't want all the threads to access it at a time so what you can do is you want to synchronize in such a way that only one thread can access this at a time so the simplest way which I have told is using a lock so when you say lock the lock expects object which it used to lock so we will create one private object may be a private static of object type Locker equal to new object this can be of any type generally we use of general object type so it doesn't matter what type of object you pass here actually so I will just pass locker and I'll put this code in this locker section so now this particular code is within so now with this code if you run you see the difference now when we see one thread starts and as soon as that thread completes other thread starts and so on so at a time you can see only one thread is able to access that so this is how lock works so this is the simplest way how you can synchronize the thread now we will see what exactly is monitor this is the code which we used for lock now we will modify this same code to use monitor so monitor is not very much different from lock the only difference is we will remove this lock and the parenthesis instead we will use monitor dot enter and this again expects an object so we will use the same Locker object and at the end we will use monitor dot exit and that object so with this again when you run you can see it behaves the same way how it was behaving for the lock but the difference when it comes to monitor is you have the flexibility of modifying the code in such a way like you can control even your exceptions like for example I can put a try block here I can put all this code inside a try block and I can have a catch so suppose if at all an exception comes in this particular part of the code I can have some error logger which you might log into a file or something and at the end in the finally block I will move this exit code into finally so now what it says is like we are starting a lock here using monitor and we are doing some work but if at all some exception happens in this area we will catch that exception do the read logging and then finally we will release that lock so if you want to try out for example here maybe I can try here I will throw a new exception so this is not the correct way how you should be doing because this is just for a trial because the moment you put here visual student starts saying unreachable code because once it is thrown an exception from here this line will never be executed so now if you execute now you see only the starting because you will not see the end message because every time exception is thrown but that exception is caught and logged and the lock is released and that is why you are seeing the next thread starting so this is of monitor works now as we have seen the simple lock and monitor methods now we will see what is manual recent event so let's consider a situation wherein you don't have a simple block of code which every time needs to be logged between threads and in such situations you cannot use lock or monitor suppose there is a writer thread which normally writes into a file and there are reader threads which reads from that file but you don't want the reader threads to read when the writer thread is writing so that means when the writer thread is in progress you don't want the reader thread to access that file so now let's try something similar so let's create a public static write method so say write oh sorry you know they shouldn't be void so public stand you can right so in this I will say console dot write line and I will simply print thread and the thread number as we have seen how we can generate it similar in the lock code thread dot current thread dot manage thread ID writing so now this writing starts and then we will simulate a situation wherein it writes for around like five seconds and then we will say the writing has completed writing completed so this is the right method similarly let's create one more read method which reads that particular file so this is the read and we'll say reading and this suppose our may be first will say waiting and we will say reading completed so now you want like when this particular method is going on you don't want these methods to be called so in such situations thus best thread synchronization method which you can use is manual reset event so let's see how we can create that you can see manual reset event under system threading the namespace you create an object of that and in this situation since we are dealing with all static methods I will have to create this also a static variable and now this expects an initial state so initial state means initially when you create this object and use it first time you want it to be in a signaled state or a non instead this I will explain how what exactly it is so let's keep it as false that is not signaled so now suppose we are starting a new thread so we'll say a new thread and this thread is the right thread so we'll say right method dot start so this is starting off a writer thread so in say starting right thread now there is a loop and in the for loop there are around like five reader threads so we'll say a new thread of great dot start so now you can see these are five reader threads and this read happens quickly whereas the writer takes around 5 seconds of time so now you want when this guy is writing you don't want anyone else to access the files so in this situation what you will do is first as soon as you say just writing MRE dot reset so reset and you can see one more method has set so this is nothing but setting the value of the event so that is like you have given the default as false so it is nothing but reset if you set it as true it is like set so you reset the manual reset event and then once the work is done you will say MRE dot set meanwhile the threads you want which you want to wait there you will say underscore Ahmadi dot wait one so let me explain what exactly is happening this is the manual reset event in this method whenever a thread comes it will check seeing this method as wait one so that means it will wait here till he gets the signal if the memory has been reset that means it's in a fault false state this guy cannot proceed unless and until he gets a signal so the signal will be provided by M re not set so let's see how this works when we press f5 you can see all one thread is writing and all the threads are waiting once writing is completed it is signaled and all the threads starts raining so maybe this was showing a delay that is because we have introduced a delay here so if you say remove this and if you say reading so maybe in this situation it'll say waiting and then it will say reading so now when you run it you can see again the thread 3 is writing rest all the threads are waiting and once thread 3 writing completes all the guys starts reading so in the manual reset event 1 set simply raises a signal to all the threads which are waiting using the same object of Amaury and as soon as a set is done all those threads starts working so this is how an ahmadi works and mostly it will be used in such situations where one thread is doing some work and you want other threads to wait till he completes his work next we will see what is auto reset event so just now we saw manual reset event wherein you found like when one thread signals all other waiting thread starts automatically whereas Auto reset event is slightly different from it so let's jump into visual studio so this was the code which I was but I have modified it strike slightly now I have only five writer threads which are writing so in this case now you might have a situation where in like a code exists which writes into a file or it does some Network related work but you don't want it to happen at a time you want the other threads to wait and only once the signal has been given by the current thread the other threads should proceed so now in such situation you can use auto reset event so that can be done by using Auto reset event which is available under system dot threading namespace and you can create some object of it and as we are dealing with static methods I will declare this gas static and again similar to how Auto manual reset event expects an initial State Auto reset event also expects an initial State so let me give the initial state as false that is non signaled so now in this situation we will introduce one more console saying similar to this writing we will say one more waiting so now so and so thread is waiting mode so now what we will do is here and we will use the a re object dot weight one so that means it should wait till he gets a signal so and at the end once he completes we should say set but now there is a catch like a first time for example you are starting five threads the first thread comes he says waiting and but when he comes here he will check what is the state of the a array which we have given as false that means you will not proceed when the second thread comes he will also wait so similarly all the five threads will be waiting but nobody will be able to give the signal so in such situation we should not be giving the initial state as false instead we should give it as true so now the first thread whoever reaches here we'll get the a re in a signaled mode so he will continue but rest of the threads will be waiting and when he signals then only the next thread will get the axis so now let's see what happens when we run this so now you see one guy is means Monday is writing rest all are waiting as soon as that guy has completed the writing another guy has got the access when he completed the next guy got the access and when he completed negative I got to access and it goes on so you can see at a time only one thread is allowed in Auto reset event whereas it is different from manual reset event wherein we use signal once and all the waiting threads just goes on but in this Auto reset event only one thread gets the access but here there is a catch now for example here in the main thread so as you know our main method is also running on a thread which is a main thread and suppose there after a sleep of around 3 seconds what I will do is I will use the same a re object and say set that means ideally the signal should be given from here but from the main thread I will use that same object and give a signal now see what happens now one thread is writing rest all are waiting now forth started writing v started writing when forth was still writing so now you can see here multiple threads are going paralleling that is two threads are going parallel why it is happening like this because we have given set from the main thread which in ideal cases should not be allowed like in its few situations you don't want any other signal to give a signal it should be like the situation wherein the thread who acts started this wait one should only give the signal so a re creates a problem in such situation in such situation our next topic comes in to help which is mutex now let's see what happens in the case of mutex so we'll jump into visual studio and this was the code which we were using for Auto reset event now we will modify this code in such a way that we use a mutex so for time being I will comment out this code and I will comment out this code as well so instead I will create a static mutex underscore mutex as an object equal to new mutex and this there is no requirement of passing the initial state in the case of mutex and here where we were using the ar e dot weight one we will use mutex dot weight one and where we were sending the signal will say mutex dot release mutex so now in this situation it works similar to how a re was working so now when let's see what happens with mutex so now one thread is writing rest all are waiting and with that thread completed writing another thread started writing that red thread completed the another thread started so it works similar to how a re is working it allows one after the other so the problem which we discussed in Erie was when we are setting the area from any other thread then our complete synchronization was going for a toss so now let's try similar to this code instead of a re I will try to set the mutex some new text art release mutex simply this is similar how we were doing for a re so now when we run this now see what happens so now one thread is writing and after two seconds it throws an exception so the exception says object synchronization method was called from an unsynchronized block of code so what this means is mutex doesn't allow calling the release mutex from outside the same thread that means if thread one has logged it only thread one has the permission to unlock it if any other thread price don't unlock it then that throws an exception so here it comes it overcomes the problem of a re so now I hope you are clear with mutex so the last topic which comes in thread synchronization is semaphore semaphore unlike mutex is not a locking mechanism where a semaphore is considered to be a signaling system so let's see how this works we'll jump into Visual Studio and this was the code which I was using for mutex so now instead of mutex I will create a semaphore it's a static same after underscore semaphore equal to new semaphore now if you see the constructor of semaphore it expects two parameters first one initial count second one maximum count so let's try giving one comma one let me show you what happens and then I will explain you the significance of this so we will remove this code and instead of using mutex now we will use semaphore so semaphore dot same like that how we used for mutex wait one and at the end semaphore dot release so similarly this is the way how it works normal thread mccannon thread synchronization mechanisms let's see what happens when we run it should work how it was working previously like all the threads are waiting one thread is writing that thread completes writing the next thread starts when that thread completes next thread starts so it goes on like how it was going for mutex or a hurry but now what comes into picture is these parameters here you can control how many threads you want to run in parallel so this is the initial count and this second parameter is the maximum cut but one thing which you need to always keep in mind is the initial count should be always less than or equal to the second one so that means like if I give here too and if I give the maximum count as one then as soon as you run it throws an exception so I'll just show you so it says the type initializer for thread synchronization demo 3 one exception so you can read the exception the initial count for sever four must be greater than or equal to zero and less than the maximum count so here the initial count was more compared to the maximum count so this is not allowed so let me change it to two so let me stop this and change it to two so now you have given the initial count as two so now you see what happens when you run now you can see thread 4 is writing thread 3 is writing third for completed 3 3 completed but meanwhile 5 & 6 started and when they both finished 7 started so now you can see two threads are going paralleling so this is kind of a signaling mechanism wherein you are trying to signal two threads at a time when the work is completed so that means two threads will start this work parallely and all the other threads will be waiting when both of them finishes then it will be given to the next one so this is how you can control it so in this video we have covered all these topics we have seen how lock and monitor locks a simple code so in most of your situations where you want to do a thing zatia for your simple code you can use lock or monitor if your code is similar in such a way wherein you want all the multiple all the threads to await when one special thread is doing some work and once that work is completed you want to signal all the threads then you can go for manual reset event or if the situation is wherein you don't want all the threads to be signaled do you want it to be signaled one after the other you can go for auto reset event but the only drawback which we serve with Auto reset event was any other thread also can signal it but you know if you don't want to do that you want only the signal only the thread which locks it should release it then go for mutex and the last we saw how semaphore works wherein we can control the number of threads to be start a signal at a time so hope this clears all the topics of thread synchronization in sisha thank you
Info
Channel: CODELLIGENT
Views: 14,571
Rating: 4.9087453 out of 5
Keywords: C#, .Net, Thread, Threading, Thread Synchronization, coding, programming
Id: 5Zv8fF-KPrE
Channel Id: undefined
Length: 26min 12sec (1572 seconds)
Published: Sat Feb 15 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.