As a C # programmer, the Lock keyword is most commonly used when encountering thread synchronization requirements. But how to use lock correctly and effectively is the key to achieving synchronization requirements efficiently. Because of this, programmers need to fully understand what lock is doing for the program.
The points of knowledge involved
Equivalent code for lock
system.threading.monitor types and how to use them
Analyze problems
1. The equivalent code of lock
In. NET multithreaded programs, you often encounter the lock keyword to control synchronization, such as the following code:
Private object o = new Object ();
public void work ()
{
Lock (O)
{
Do some work that requires thread synchronization
}
}
In fact, the keyword lock is a syntax defined by C # for the convenience of programmers, which is equivalent to safely using the System.Threading.Monitor type. The code above is directly equivalent to the following code:
Private object o = new Object ();
public void work ()
{
It is important here to avoid direct use of Private member O, which leads to thread insecurity
Object temp = o;
System.Threading.Monitor.Enter (temp);
Try
{
Do some work that requires thread synchronization
}
Finally
{
System.Threading.Monitor.Exit (temp);
}
}
As you can see, the real thread synchronization feature is the System.Threading.Monitor type, the lock keyword is simply used instead of calling the Enter, exit method, and all the work is included in the try block to ensure that it eventually exits the synchronization.
2. Role and use of the System.Threading.Monitor type
As mentioned in the previous article, the Enter and exit methods of the monitor type are used to achieve the synchronization of entry and exit objects. Specifically, when the Enter method is called, the synchronization index of the object is checked, and. NET will be responsible for a series of subsequent work to ensure that the thread is synchronized while the object accesses, and the call of the exit method guarantees that the current thread frees the object's synchronization block.
Example
The following demonstrates how a custom class can use the Lock keyword (that is, the monitor type) to implement thread synchronization, and defines a type that contains a method that requires synchronous execution.
<summary>
Demo Sync Lock
</summary>
public class MyLock
{
Used to synchronize in a static method
private static Object O1 = new Object ();
Used in different member methods
Private Object O2 = new Object ();
Member variables
private static int i1 = 0;
private int i2 = 0;
<summary>
To test the synchronization of a static method
</summary>
<param name= "Handleobject" > Objects to be manipulated during synchronization </param>
public static void Increment1 (object handleobject)
{
Lock (O1)
{
Console.WriteLine (The value of "I1: {0}", I1);
This deliberately creates thread parallelism to check the functionality of synchronization
Thread.Sleep (200);
i1++;
Console.WriteLine ("I1 since increment: {0}", I1);
}
}
<summary>
To test the synchronization of member methods
</summary>
<param name= "Handleobject" > Objects to be manipulated during synchronization </param>
public void Increment2 (object handleobject)
{
Lock (O2)
{
Console.WriteLine (The value of "I2: {0}", I2);
This deliberately creates thread parallelism to check the functionality of synchronization
Thread.Sleep (200);
i2++;
Console.WriteLine ("I2 since increment: {0}", I2);
}
}
}
This way, in the main method, the method of the type object is called and its static method is used to test the effect of its synchronization. The code is as follows
<summary>
Program entry
</summary>
Class Program
{
<summary>
Test the Sync effect
</summary>
static void Main (string[] args)
{
Start multithreading
Console.WriteLine ("Start testing the synchronization of static methods");
for (int i = 0; i < 5; i++)
{
Task T = new Task (mylock.increment1, i);
T.start ();
}
Here wait for thread execution to end
Thread.Sleep (3 * 1000);
Console.WriteLine ("Starting to test the synchronization of member methods");
MyLock MyLock = new MyLock ();
Start multithreading
for (int i = 0; i < 5; i++)
{
Thread t = new thread (MYLOCK.INCREMENT2);
T.start ();
}
Console.read ();
}
}
Here is the result of the program execution:
Start testing the synchronization of static methods
The value of the I1 is: 0
I1 after self-increment: 1
The value of the I1 is: 1
I1 after self-increment: 2
The value of the I1 is: 2
I1 after self-increment: 3
The value of the I1 is: 3
I1 after self-increment: 4
The value of the I1 is: 4
I1 after self-increment: 5
To start the synchronization of test member methods
The value of the i2 is: 0
I2 after self-increment: 1
The value of the i2 is: 1
I2 after self-increment: 2
The value of the i2 is: 2
I2 after self-increment: 3
The value of the i2 is: 3
I2 after self-increment: 4
The value of the i2 is: 4
I2 after self-increment: 5
Summary
As you can see, thread synchronization is well guaranteed. It should be emphasized that thread synchronization itself violates the principle of multithreading parallel running, so readers should try to add lock to the smallest block when using thread synchronization. If a method has a lot of code need to thread synchronization, it needs to reconsider the design of the program, whether it is really necessary to multithreading, after all, the cost of the thread itself is quite large.
For static method synchronization, the static private reference members are generally used, whereas the synchronization of member methods generally employs a private reference member. Readers need to pay attention to the use of both static and non-static members, all of which declare the synchronization object as private, which is the key point to ensure the thread synchronization is efficient and correct.
Description: The above content is organized according to the content of the Internet.
What does the lock keyword in C # do?