Several thread synchronization object methods in C #

Source: Internet
Author: User

It is not possible to avoid thread synchronization problems when writing multithreaded programming. What is thread synchronization?

For example: If there is a variable in a company that records the salary of a person's T, there are two supervisors A and B (that is, the worker thread) who took the value of the variable back in the count=100.
, after a period of time a supervisor adds T's salary to 5, and returns the count variable, while the B supervisor subtracts the wages of T by 3 and returns the Count variable. Well, the original T-June can get 102 dollars of wages, now become 98 dollars. This is the problem that thread synchronization solves.

In some objects of. NET, the data can be modified while reading the data inside, and this type of object is "thread safe". However, for the code snippets that you write, you must use thread synchronization technology to ensure the integrity and correctness of the data.

There are several rules:
1. If an object (or variable) is not accessed by multiple other threads at the same time, then this object is not required to use thread synchronization.
2. If there are multiple threads accessing an object at the same time, but the data or method they are accessing is not the same (not intersecting), then this situation does not need to use thread synchronization.
For example, in the previous example of the company if there are T and Q two people, but their salary is a and B in charge, then the processing of this wage does not need to synchronize the thread.
3. If an object is accessed by multiple other threads at the same time, it is generally only necessary to add thread-synchronized code to the object, while other threads do not need to add additional code.

There are several classes of common classes used to implement thread synchronization in C #
1. Mutex class (mutex), monitor class, lock method
2, ManualResetEvent class, AutoResetEvent class (both of which are derived from the EventWaitHandle class)
3, ReaderWriterLock Class

The same kind of role is similar:
The function of the first class is to protect a piece of code from being executed in an exclusive manner when the second thread wants to access the object. Wait until the exclusive
Code to execute. Like a bunch of people at the same time a public toilet, the use of this method can be used to solve the problem at the beginning of the article: Supervisor A to deal with T-June before the salary, first lock the T-June, and then remove the current count value, after processing and then release T-June lock. If Supervisor B wants to remove the count value when the supervisor a is working on the payroll, it can only wait until the a process has finished before continuing. One disadvantage of using this method is that it reduces the efficiency of the program. It would have been a multiple-thread operation, and once the lock statement was encountered, those threads would have been queued for the same single-threaded operation.

Here's an example of how these three methods are used:
Suppose you have an tools class, an int variable, and an Add and delete method, where the Add method increases the value of the int variable, and the Delete method reduces the value of the INT variable:

public class Tools
{
private int count = 100;
public void Add (int n)
{
Count+=n;
}

public void Delete (int n)
{
Count-=n;
}
}

When multiple threads access this code at the same time, because a statement is compiled into multiple instructions by the compiler, this can happen: But when a thread calls the Add method, the Count value is 100, and when you add N, another thread calls delete, which subtracts m, The result of Count plus N, and then in the case of the original count=100 value
Minus M, the final result is that count is subtracted from m, without adding N. It is obvious that the Add method and the Delete method cannot be called at the same time, so thread synchronization must be done. The simple approach is to use the lock statement:

public class Tools
{
Private Object ABCDE = new Object ();
private int count = 100;

public void Add (int n)
{
Lock (ABCDE)
{
Count+=n;
}
}

public void Delete (int n)
{
Lock (ABCDE)
{
Count-=n;
}
}
}

Where ABCDE is a private class internal variable, it does not represent any meaning, just as a "token" role.
When executing the lock (ABCDE) method in the Add method, the token is in the hands of the Add method, and if there is a second thread that wants to take the token, no way, just wait. Once the first
After the closing of the curly brace of the lock statement, the season card is released, and it quickly falls to the second thread and excludes the others later.

The method of using the monitor class is roughly the same:

public class Tools
{
Private Object ABCDE = new Object ();
private int count = 100;

public void Add (int n)
{
Monitor.Enter (ABCDE);
Count+=n;
Monitor.Exit (ABCDE);
}

public void Delete (int n)
{
Monitor.Enter (ABCDE);
Count-=n;
Monitor.Exit (ABCDE);
}
}

Common methods for Monitor: Both enter and Exit are static methods, with the same effect as the two curly braces of a lock statement.
A Mutex is not required to declare a "token" object, but it can be used only after it is instantiated:

public class Tools
{
Private Mutex Mut = new Mutex ();
private int count = 100;

public void Add (int n)
{
Mut. WaitOne ();
Count+=n;
Mut. ReleaseMutex ();
}

public void Delete (int n)
{
Mut. WaitOne ();
Count-=n;
Mut. ReleaseMutex ();
}
}

The

WaitOne is the wait method until the mutex is released. Initially, the Mutex object is in the released state, and once the WaitOne method is executed, it  
is captured. The ReleaseMutex method was not released until it was called.  
using these three methods has one problem to be aware of is that in an exclusive code snippet, if an exception is caused, the "token" object may not be released. So the program will be death all the way down.  
so the exception should be handled in the exclusive code snippet. For example, the following code is wrong:

public void Add (int n)  
{ Try 
{ 
Mut. WaitOne ();  
Count+=n;//.... This omits the N line code  
//.... Here is the code that is likely to cause an exception  
/.... This omits the N-line code  
Mut. ReleaseMutex ();  
} 
Catch 
{ 
Console.WriteLine (" Error. ");  
} 
}

Once the above code has an exception in the try and catch, the mutex cannot be freed, and the subsequent program will be stuck in the WaitOne () line, and it should be changed to this:

public void Add (int n)  
{ Mut. WaitOne ();  
Try 
{ 
Count+=n;//.... This omits the N line code  
//.... Here is the code that is likely to cause an exception  
/.... This omits the N line code  
} 
catch< Span class= "Apple-converted-space" >&NBSP;
{&NBSP;
Console.WriteLine (" Error. "); &NBSP;
}&NBSP;
Mut. ReleaseMutex (); &NBSP;
}

Now let's talk about the second type:
ManualResetEvent class, AutoResetEvent class

The above two classes are all derived from the EventWaitHandle class, so the functionality and invocation methods are very similar.
These two classes are often used to block the execution of a thread, and then resume its execution if the condition is met.
For example, you want to send flowers to a mm, give a flower to send the lad to the past, and you want to when the MM received the flowers immediately after a call to tell her.

But the problem is that you do not know when the flowers are sent to the MM hand, early to play late is not good, then you can use the ManualResetEvent object to help. When the commission

When the lad sends flowers to the past, use ManualResetEvent's WaitOne method to wait. When the lad sends the flowers to MM's hands, call again

ManualResetEvent the Set method, you will be able to call the past on time.
ManualResetEvent also has a reset method, which is used to re-block the caller's execution, as if you had entrusted the lad to send flowers to n mm,

and want to be on time to call the N-mm the same situation.

Using System;
Using System.Threading;

public class Testmain
{
private static ManualResetEvent ent = new ManualResetEvent (false);

public static void Main ()
{
Boy sender = new boy (ENT);
Thread th = new Thread (new ThreadStart (sender). Sendflower));
Th. Start ();

Ent. WaitOne (); Waiting for work
Console.WriteLine ("I received it, the flower is I send a beep:)");
Console.ReadLine ();
}

}

public class Boy
{
ManualResetEvent ent;

Public Boy (ManualResetEvent e)
{
ent = e;
}

public void Sendflower ()
{
Console.WriteLine ("On the way to send Flowers");
for (int i = 0; i <; i++)
{
Thread.Sleep (200);
Console.Write ("..");
}
Console.WriteLine ("Flower has been sent to mm hands, boss");

Ent. Set (); Notifies the blocking program
}
}

And the AutoResetEvent class is called the meaning, is in each set after the end of the automatic reset. Let the executor re-enter the blocking state.
That is, AutoResetEvent.Set () is equivalent to Manualresetevent.set () and immediately manualresetevent.reset (),
There's nothing different about the rest.
Give an example of sending flowers to n mm:

Using System;
Using System.Threading;

public class Testmain
{
private static AutoResetEvent ent = new AutoResetEvent (false);

public static void Main ()
{
Boy sender = new boy (ENT);

for (int i = 0; i < 3; i++)
{
Thread th = new Thread (new ThreadStart (sender). Sendflower));
Th. Start ();
Ent. WaitOne (); Waiting for work
Console.WriteLine ("Got it, the flower is I send a beep:) ");
}

Console.ReadLine ();
}

}

public class Boy
{
AutoResetEvent ent;

Public Boy (AutoResetEvent e)
{
ent = e;
}

public void Sendflower ()
{
Console.WriteLine ("On the way to send Flowers");
for (int i = 0; i <; i++)
{
Thread.Sleep (200);
Console.Write ("..");
}
Console.WriteLine ("Flower has been sent to mm hands, boss");

Ent. Set (); Notifies the blocker that the effect here is equivalent to ManualResetEvent's set () method +reset () method
}
}

Several thread synchronization object methods in C #

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.