[C # Basics] Who is locked by lock ?,

Source: Internet
Author: User

[C # Basics] Who is locked by lock ?,
Preface

I have been working on file transfer components for the past month. multithreading technology is used, but in some cases, only one thread is required to operate. How can I ensure that there is only one thread? The first thing that comes to mind is the concept of locks. The most recently heard about locks in our project team is who. How can we lock them? Seeing that some colleagues use lock (this) and lock (private static object), it is a bit confusing. Who is the most suitable lock?

Lock

First, go to the official Msdn statement.

The lock keyword ensures that when a thread is located in the Code critical section, the other thread does not enter the critical section. If other threads attempt to enter the locked code, it waits until the object is released.
The lock keyword calls Enter at the beginning of the block, and Exit at the end of the block. ThreadInterruptedException is triggered if Interrupt interrupts the thread waiting for the lock statement to be entered.
In general, do not lock the public type; otherwise, the instance will be out of the control scope of the Code.

Common structures such as lock (this), lock (typeof (MyType), and lock ("myLock") violate this rule:
If the instance can be accessed by the public, the lock (this) problem occurs.
If MyType can be accessed by the public, the lock (typeof (MyType) problem will occur.
Any other code that uses the same string in the process will share the same lock, so the lock ("myLock") problem occurs.
The best practice is to define private objects to lock, or private static object variables to protect the data shared by all instances.
The waiting keyword cannot be used in the body of the lock statement.

Enter refers to Monitor. Enter (obtain the exclusive lock on the specified object .), Exit refers to Monitor. Exit (release the exclusive lock on the specified object .)

With the above msdn explanation and Exit method, you can guess that "until this object is released", "This object" should be the lock object, the object has been released or the object has changed, other threads can enter the code critical section (can this be understood ?).

In multiple threads, each thread has its own resources, but the code zone is shared, that is, each thread can execute the same function. This may cause several threads to execute a function at the same time, resulting in data confusion and unexpected results. Therefore, we must avoid this situation.

For example, in this scenario, the toilets in the buildings where many companies are located are in small single rooms, that is, they can only enter one person at a time. To avoid entering one person at a time, what should we do? Isn't it because a person locks the door after going in? In this way, the people outside will only wait for you to complete the liberation before you can enter. While resources (such as squatting and toilet paper) are shared.

The most commonly used lock is the code segment in the following format:

Private static object objlock = new object (); lock (objlock) {// code logic to be executed}

Why is the Lock Object private? Take the toilet as an example. Private is like, this lock is only accessible to you, and it is better that this lock will not be changed because of external force, and others will not be able to access it, so as to ensure that you are in, others cannot enter. If it is public, it is like the lock in your cell is not installed inside, but installed outside. If someone else wants it, it is not what you can control, this is also not safe.

Lock (this)

It literally means the current instance object of the lock. Does it affect other instance objects? Here is an example:

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 in a loop. 13 threads [I] = new Thread () => 14 {15 t2.Print (); 16}); 17 // set a name for each Thread 18 threads [I]. name = "thread" + I; 19 20} 21 // start the ten created threads 22 for (int I = 0; I <threads. length; I ++) 23 {24 threads [I]. start (); 25} 26 27 Console. read (); 28} 29} 30 class Test31 {32 public void Print () 33 {34 lock (this) 35 {36 for (int I = 0; I <5; I ++) 37 {38 Console. writeLine ("\ t" + Thread. currentThread. name. toString () + "\ t" + I. toString () + ""); 39} 40} 41} 42} 43}

If no lock is applied, the output is as follows:

From the above output, we can see that the thread is competing, and this is not the result we want. What we want is that there is only one thread at a time to execute the Print method. 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() + " ");10                 }11             }12         }13     }

Output result

From the output results, I thought it was a success, but now the situation is coming again. In other places in the project, some colleagues wrote this code and created another Test object, he also knows how to use multiple threads to execute time-consuming work, so 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 in a loop. 14 threads [I] = new Thread () => 15 {16 t. print (); 17 t2.Print (); 18}); 19 // set a name of 20 threads [I] for each thread. name = "thread" + I; 21 22} 23 24 25 // enable the created ten threads 26 for (int I = 0; I <threads. length; I ++) 27 {28 threads [I]. start (); 29} 30 31 Console. read (); 32} 33} 34 class Test35 {36 public int Age {get; set;} 37 public void Print () 38 {39 lock (this) 40 {41 for (int I = 0; I <5; I ++) 42 {43 Console. writeLine ("\ t" + Thread. currentThread. name. toString () + "\ t" + I. toString () + ""); 44} 45} 46} 47} 48}

Here, an Age attribute is added to Test to distinguish the currently created object from the same object.

The output result is

The thread preemptible execution has already occurred in the output results, rather than being executed by one thread after another.

Lock (private obj)

Now we can use a global private object for a try.

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 in a loop. 15 threads [I] = new Thread () => 16 {17 lock (objLock) 18 {19 t. print (); 20 t2.Print (); 21} 22}); 23 // set a name for each thread 24 threads [I]. name = "thread" + I; 25 26} 27 28 29 // enable the created ten threads 30 for (int I = 0; I <threads. length; I ++) 31 {32 threads [I]. start (); 33} 34 35 Console. read (); 36} 37} 38 class Test39 {40 public int Age {get; set;} 41 public void Print () 42 {43 for (int I = 0; I <5; I ++) 44 {45 Console. writeLine ("\ t" + Thread. currentThread. name. toString () + "\ t" + I. toString () + ""); 46} 47} 48} 49}

Output result

From the output results, we can also see that, in order, every time a thread comes in for execution.

Through the comparison above, we can conclude that the lock result is good, but the key is to see who the lock is. If the lock can be modified on the outside, the lock will be ineffective. In general, static and read-only objects are used.

The following code is also available:

1  private static readonly object objLock = new object();

You may say, No. The code below is different from the code above. Why did you come to this conclusion? Isn't it possible to put the Object in the test class? If it is in the test class, it is also possible to put the Object in the new Test () class, you only need to ensure that the objLock cannot be modified externally.

The most mentioned above is the lock Object. Can it lock the value type?

The answer is no, for example

Of course, lock (null) also does not work,

Although the compilation is successful, an error occurs during running.

Lock (string)

String is also an application type, which is correct in syntax.

However, locking a string is especially dangerous because the string is "Temporarily" by the Common Language Runtime Library (CLR ". This means that there is only one instance for any given string in the entire program, and the same object represents the text in all threads in all running application domains. Therefore, as long as a lock is placed on a string with the same content anywhere in the application process, all instances of the string in the application will be locked. Generally, it is better to avoid locking the public type or locking an object instance that is not controlled by the application. For example, if the instance can be publicly accessed, lock (this) may be faulty because uncontrolled Code may also lock the object. This may cause a deadlock, that is, two or more threads are waiting to release the same object. For the same reason, locking public data types (compared to objects) may also cause problems. Besides, lock (this) is only valid for the current object. If multiple objects cannot be synchronized. Lock (typeof (Class) is the same as locking a string and has a wide range.

Summary

Here is the introduction of lock. The following points should be noted:

1. lock objects of the reference type, except those of the string type.

2. The recommended lock method is to use static, read-only, and private objects.

3. It makes sense to ensure that the lock object cannot be modified externally. If the lock object changes externally, it will be unobstructed to other threads and lose the meaning of lock.

References

Http://www.cnblogs.com/jintianhu/archive/2010/11/19/1881494.html

Reference page: http://qingqingquege.cnblogs.com/p/5933752.html

Related Article

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.