Lock
First on the official MSDN version.
The lock keyword ensures that when one thread is in the critical section of the code, the other thread does not enter the critical section. If another thread attempts to enter the locked code, it waits (that is, is blocked) until the object is freed.
The Lock keyword calls Enter at the beginning of the block, and Exit is called at the end of the block. ThreadInterruptedException thrown if Interrupt interrupts the thread waiting to enter the lock statement.
In general, you should avoid locking the public type, or the instance will go beyond the control of your code.
Common structure Lock (this), Lock (typeof (MyType)) and lock ("MyLock") violate this guideline:
If the instance can be accessed publicly, the lock (this) issue occurs.
If MyType can be accessed publicly, a lock (typeof (MyType)) issue will occur.
The Lock ("MyLock") issue occurs because any other code that uses the same string in a process will share the same lock.
The best practice is to define private objects to lock, or private static object variables to protect data that is common to all instances.
The wait keyword cannot be used in the body of the lock statement.
Enter refers to Monitor.Enter (gets the exclusive lock on the specified object. ), Exit refers to Monitor.Exit (frees an exclusive lock on the specified object. )
With the above MSDN explanation and the exit method, you can guess "until the object is released", "the object" should be the object that refers to the lock, the object is freed or the object changes, other threads can enter the Code critical section (Is it possible to understand?). )。
In multi-threading, each thread has its own resources, but the code area is shared, that is, each thread can execute the same function. The problem is that several threads execute a function at the same time, causing the data to clutter and produce unpredictable results, so we have to avoid this happening.
For example, there is such a situation, many companies are located in the building of the toilet squat is a small single-room type, that is, only one person at a time, then in order to avoid every time in a person, how to do it? Isn't it just a guy who goes in and locks the door? So what you do in it, the outside people can only wait for you to be liberated, to enter. and squatting resources (squatting, toilet paper, etc.) are shared.
The most commonly used locks are code snippets in the following format:
private static Object Objlock = new Object (); Lock (Objlock) { //code logic to execute}
Why is the object of the lock private? Or the toilet as an example, the private is like, this lock only you can access, and the best this lock will not because of external forces and change, others can not access, so as to ensure that you go in, others will not go, if it is public, it is like you squat small single-room lock is not installed in the inside but installed in the outside, It's not safe for others to want to get in, and it's not something you can control.
Lock (This)
By literal means is the current instance object of the lock. Does that have an impact on other instance objects? Let's look at an example below:
1 namespace Wolfy.lockdemo 2 {3 class program 4 {5 static void Main (string[] args) 6 {7 Test T = new Test (); 8 Test t2 = new Test (); 9 thread[] Threads = new thread[10];10 for (int i = 0; i < threads. Length; i++) 11 {12//create 10 threads through a loop. Threads[i] = new Thread (() =>14 {t2. Print (); 16}); 17//Set a name for each thread threads[i]. Name = "Thread" + i;19 20}21//Open 10 threads created for (int i = 0; i < threads. Length; i++) [Threads[i]. Start ();}26 console.read ();}29}30 class Test31 {public Vo ID Print () {(this) {i++) (int i = 0; i < 5;) 37 {Console.WriteLine ("\ T" + Thread.CurrentThread.Name.ToString () + "\ T" + i.tostring () + "" "); 39}40}41}42 }43}
If the output is the following without locking:
As can be seen from the above output, there is a scramble for threads, which is not the result we want, and we want to have only one thread to execute the Print method at a time. Then let's try Lock (this)
1 class Test 2 {3 public void Print () 4 {5 lock [This] 6 {7 for (int i = 0; i < 5; i++) 8 {9 Console.WriteLine ("\ T" + Thread.CurrentThread.Name.ToString () + "\ T" + i.tostring () + ""); c12/>}12 }13 }
Output results
From the output, think it's done, but now it's here again, in other parts of the project, a colleague has written this code, created a test object, and he knows that using multithreading to do time-consuming work, the following code will appear.
1 namespace Wolfy.lockdemo 2 {3 class program 4 {5 static void Main (string[] args) 6 {7 Test T = new Test (); 8 Test t2 = new Test (); 9 T2. Age = 20;10 thread[] threads = new thread[10];11 for (int i = 0; i < threads. Length; i++) 12 {13//create 10 threads through a loop. Threads[i] = new Thread (() =>15 {t.print (); 17 T2. Print (); 18}); 19//Set a name for each thread threads[i]. Name = "Thread" + i;21 22}23 24 25//Open 10 threads created for (int i = 0; i < threads. Length; i++) {Threads[i]. Start ();}30 to Console.read ();}33}34 class Test35 {in T age {get; set;} PNs public void Print () 40 {41 for (int i = 0; i < 5; i++) Console.WriteLine ("\ T" + THREAD.CURRENTTH Read. Name.tostring () + "\ T" + i.tostring () + "" "); 44}45}46}47}48}
This adds an age property for test, in order to distinguish between objects that are currently created that are not the same object.
The result of the output is
In the result of the output, there has been a thread preemption execution, not one thread executing another thread.
Lock (Private obj)
So let's try it now with a global private object.
1 namespace Wolfy.lockdemo 2 {3 class program 4 {5 private static object Objlock = new Object (); 6 static void Main (string[] args) 7 {8 Test t = new Test (); 9 Test t2 = new test (); 10 T2. Age = 20;11 thread[] threads = new thread[10];12 for (int i = 0; i < threads. Length; i++) 13 {14//create 10 threads through a loop. Threads[i] = new Thread (() =>16 {18 Lock (Objlock) {t.print (); T2. Print (); 21}22}); 23//Set a name for each thread threads[i]. Name = "Thread" + i;25 26}27 28 29//Open 10 threads created for (int i = 0; i < threads. Length; i++) {Threads[i]. Start ();}34 console.read ();}37}38 CLASS Test39 {+ public int: Age {get; set;} 0 public void Print () (int i =; i < 5; i++) 44 {45 Console.WriteLine ("\ T" + Thread.CurrentThread.Name.ToString () + "\ T" + i.tostring () + ""); 46}47}48 }49}
Results of the output
The results from the output can also be seen, ordered, every time a thread executes.
That through the above comparison can have such a conclusion, the result of lock is not good, or the key to see who the lock, if the outside can be modified for this, lock lost the role. Therefore, in general, static and read-only objects are used.
There is a code like the following
1 private static readonly Object Objlock = new Object ();
You might say, no, the following code is not the same as the code above, why did you come to this conclusion? Can not put object in the test class, put in the test class, in the new test (), in fact, it is also possible to put in test, as long as the guarantee that the objlock outside is not modifiable.
Most of the above is the lock object, then it can lock value type?
The answer is no, like
Of course lock (NULL) is also not possible,
Although the compilation can be passed, the operation will go wrong.
Lock (String)
String is also an application type, which is syntactically correct.
Locking a string, however, is especially risky because the string is persisted by the common language runtime (CLR). This means that there is only one instance of any given string in the entire program, which is the same object that represents the text in all the threads of all running application domains. Therefore, whenever a lock is placed on a string that has the same content anywhere in the application process, all instances of that string in the application are locked. In general, it is a good idea to avoid locking public types or locking object instances that are not under application control. For example, if the instance can be publicly accessible, lock (this) may be problematic because uncontrolled code may also lock the object. This can result in a deadlock, where two or more threads wait to release the same object. For the same reason, locking public data types (compared to objects) can also cause problems. and lock (this) is only valid for the current object, if the synchronization effect is not achieved between multiple objects. Lock (typeof (Class)) is too wide to be the same as a locked string.
Summarize
The introduction of lock is here, there are a few points to note
1. Lock is an object of reference type, except for string type.
2. The recommended practice for lock is to use static, read-only, private objects.
3, to ensure that the lock object can not be modified outside the meaning, if the lock object is changed outside, the other threads will be unimpeded, lost the meaning of lock.
Reference articles
Http://www.cnblogs.com/jintianhu/archive/2010/11/19/1881494.html
Reference page: http://qingqingquege.cnblogs.com/p/5933752.html
[C # Basics] Tell me, who is lock locked?