Scrigroup - Documente si articole

     

HomeDocumenteUploadResurseAlte limbi doc
AccessAdobe photoshopAlgoritmiAutocadBaze de dateCC sharp
CalculatoareCorel drawDot netExcelFox proFrontpageHardware
HtmlInternetJavaLinuxMatlabMs dosPascal
PhpPower pointRetele calculatoareSqlTutorialsWebdesignWindows
WordXml

AspAutocadCDot netExcelFox proHtmlJava
LinuxMathcadPhotoshopPhpSqlVisual studioWindowsXml

The Enter() and Exit() Methods

c



+ Font mai mare | - Font mai mic



The Enter() and Exit() Methods

It is important to note that the Monitor methods are static and can be called on the Monitor class itself rather than an instance of that class. In the .NET Framework, each object has a lock associated with it that can be obtained and released so that only one thread at any time can access the object's instance variables and methods. Similarly, each object in the .NET Framework also provides a mechanism that allows it to be in a waiting state. Just like the lock mechanism, the main reason for this mechanism is to aid communication between threads. The need for such mechanism arises when one thread enters the critical section of an object and needs a certain condition to exist and assumes that another thread will create that condition from the same critical section.



The trick is now that only one thread is allowed in any critical section at any point of time, and when the first thread enters the critical section, no other thread can. So, how will the second thread create a condition in the critical section when the first thread is already in it? For example, if thread A has to get some data from the database and another thread B has to wait until all the data is received and then process the data, thread B calls the Wait() method and waits for thread A to notify it when the data arrives. When the data does arrive, A calls the Pulse() method, which notifies B so that B can process the data. This is achieved by the 'Wait and Pulse' mechanism. The first thread enters the critical section and executes the Wait() method. The Wait() method releases the lock prior to waiting and the second thread is now allowed to enter the critical section, changes the required condition, and calls the Pulse() method to notify the waiting thread that the condition has been reached and it can now continue its execution. The first thread then reacquires the lock prior to returning from the Monitor.Wait() method and continues execution from the point where it called Monitor.Wait().

No two threads can ever enter the Enter() method simultaneously. It is analogous to an ATM machine where only one person is allowed to operate at any point of time and no one else can get their chance until after the first person leaves. You can see that the names Enter and Exit have been chosen very aptly. Figure 2 illustrates the Monitor functionality.


Figure 2

Let's see an example of using the Enter() and Exit() methods, MonitorEnterExit.cs:

using System;
using System.Threading;

namespace MonitorEnterExit


public void NonCriticalSection()


Console.WriteLine('Exiting Thread ' +
Thread.CurrentThread.GetHashCode());

public void CriticalSection()


Console.WriteLine('Exiting Thread ' +
Thread.CurrentThread.GetHashCode());

//Exit the Critical Section
Monitor.Exit(this);


public static void Main(String[] args)

else




When you run the application without providing an input parameter you will get the output from the CriticalSection() method as follows:

Entered Thread 2
Result = 0 ThreadID 2
Result = 1 ThreadID 2
Result = 2 ThreadID 2
Result = 3 ThreadID 2
Result = 4 ThreadID 2
Exiting Thread 2
Entered Thread 3
Result = 5 ThreadID 3
Result = 6 ThreadID 3
Result = 7 ThreadID 3
Result = 8 ThreadID 3
Result = 9 ThreadID 3
Exiting Thread 3

Conversely, when you provide an input parameter, the corresponding output will be from the NonCriticalSection() method:

Entered Thread 2
Result = 0 ThreadID 2
Entered Thread 3
Result = 1 ThreadID 3
Result = 2 ThreadID 2
Result = 3 ThreadID 3
Result = 4 ThreadID 2
Result = 5 ThreadID 3
Result = 6 ThreadID 2
Result = 7 ThreadID 3
Result = 8 ThreadID 2
Result = 9 ThreadID 3
Exiting Thread 2
Exiting Thread 3

In the above example, we declare an EnterExit class with a global result variable and two methods: NonCriticalSection() and CriticalSection(). In the NonCriticalSection() section we don't specify any monitors to lock the section, while in the CriticalSection() method we lock the critical section using a monitor. Both the methods modify the value of result.

The critical section is defined as the code block between the Monitor.Enter(this) and Monitor.Exit(this) lines. The this parameter indicates that the lock should be held on the current object in consideration. It is always confusing to decide on which object to pass into the Enter() method as a parameter. When you need to lock the object so that no other thread can access the object under consideration, pass a this pointer as the parameter. For example, in the AccountWrapper example previously discussed, we passed the Account object to the Monitor, rather than a this pointer of the AccountWrapper object. This was because our intention was to lock the Account object and not the AccountWrapper object. We don't want multiple threads to access the Account object, but we don't mind multiple threads accessing AccountWrapper object.

In the Main method, we run the appropriate methods based on the arguments provided. If no argument is supplied, we use the CriticalSection() method and, if any argument is supplied, we use the NonCriticalSection() method. In both the cases, we have two threads accessing the methods, started from the Main method, at the same time and changing the result variable. Though they are declared sequentially, the For loop and the sleep time will ensure that the threads will try to compete for resources.

Comparing the outputs of the critical and non-critical sections makes the concept of critical sections clear. If you observe the output from the NonCriticalSection() method, both the threads nt1 and nt2 are changing the result variable at the same time, thus resulting in a mixed output. This is because there are no locks in the NonCriticalSection() method and thus the method is not thread-safe. Multiple threads can access the method and so the global variable at the same time. On the other hand, if you observe the output from the CriticalSection() method, it is clear that until the thread ct1 exits the critical section, no other thread (ct2 in this case) is allowed access to the critical section.



Politica de confidentialitate | Termeni si conditii de utilizare



DISTRIBUIE DOCUMENTUL

Comentarii


Vizualizari: 727
Importanta: rank

Comenteaza documentul:

Te rugam sa te autentifici sau sa iti faci cont pentru a putea comenta

Creaza cont nou

Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved