Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use C # multithread locks lock and Monitor

2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

In this article, the editor introduces in detail "how to use lock and Monitor of C# multithread locks". The content is detailed, the steps are clear, and the details are handled properly. I hope that this article "how to use lock and Monitor of C# multithread locks" can help you solve your doubts. Following the editor's train of thought, let's learn new knowledge.

1,Lock

Lock is used to read a reference type for locking, and only one thread can access this object at a time. Lock is a grammatical sugar and is implemented through Monitor.

The object locked by Lock should be a static reference type (except for strings).

In fact, a string can also be used as an object of a lock, but because of the particularity of the string object, it may cause conflicts between different threads in different locations.

If you can guarantee the uniqueness of a string, such as a string generated by Guid, it can also be used as an object of a lock (but not recommended).

The object of the lock does not have to be static, but can also be used as a lock object through the member variables of the class instance.

Lock prototype

Lock is the syntax sugar of Monitor, the generated code comparison:

Lock (x) {/ / Your code...} object _ _ lockObj = x Bool _ _ lockWasTaken = false;try {System.Threading.Monitor.Enter (_ _ lockObj, ref _ _ lockWasTaken); / / Your code...} finally {if (_ _ lockWasTaken) System.Threading.Monitor.Exit (_ _ lockObj);}

Ignore Monitor here, and we'll talk about it later.

Writing an example of lock

First of all, if you write like this, pull out and play si.

Public void MyLock () {object o = new object (); lock (o) {/ /}}

Let's write a simple lock, with an example as follows:

Class Program {private static object obj = new object (); private static int sum = 0; static void Main (string [] args) {Thread thread1 = new Thread (Sum1); thread1.Start (); Thread thread2 = new Thread (Sum2); thread2.Start () While (true) {Console.WriteLine ($"{DateTime.Now.ToString ()}:" + sum); Thread.Sleep (TimeSpan.FromSeconds (1));}} public static void Sum1 () {sum = 0 Lock (obj) {for (int I = 0; I < 10; iTunes +) {sum + = I; Console.WriteLine ("Sum1"); Thread.Sleep (TimeSpan.FromSeconds (2)) } public static void Sum2 () {sum = 0; lock (obj) {for (int I = 0; I < 10; iTunes +) {sum + = 1; Console.WriteLine ("Sum2") Thread.Sleep (TimeSpan.FromSeconds (2));}}

Class sets itself as a lock, which prevents malicious code from adopting locks on public objects.

For example:

Public void Access () {lock (this) {}}

Locks can prevent other threads from executing the code in the lock block (lock (o) {}). When locked, other threads must wait for the thread in the lock to complete execution and release the lock. But this may have a performance impact on the program.

Locks are not very suitable for Imax O scenarios, such as file Imax O, complicated calculations or long-lasting operations, which will bring a great loss of performance to the program.

10 ways to optimize the performance of locks: http://www.thinkingparallel.com/2007/07/31/10-ways-to-reduce-lock-contention-in-threaded-programs/

2,Monitor

This object provides a mechanism to access the object synchronously; Monotor is a static type with few methods, and the common methods are as follows:

Operation instructions Enter, TryEnter acquire the lock of the object. This action also marks the beginning of the key section. No other thread can enter the critical section unless it uses a different locked object to execute the instructions in the critical section. Wait releases locks on the object to allow other threads to lock and access the object. The calling thread waits for another thread to access the object. A pulse signal is used to notify the waiting thread of a change in the state of the object. Pulse and PulseAll send signals to one or more waiting threads. The signal notifies the waiting thread that the state of the locked object has changed and the owner of the lock is ready to release the lock. The waiting thread is placed in the object's ready queue, so it may eventually receive the object's lock. After the thread is locked, it can check the new state of the object to see if the desired state has been reached. Exit releases the lock on the object. This action also marks the end of the critical section protected by the locked object. How to use it?

Here is a simple example:

Private static object obj = new object (); private static bool acquiredLock = false; public static void Test () {try {Monitor.Enter (obj, ref acquiredLock) Catch {} finally {if (acquiredLock) Monitor.Exit (obj);}}

Monitor.Enter locks the obj object and sets acquiredLock to true to tell others that obj is locked.

At the end, determine the acquiredLock, release the lock, and set acquiredLock to false.

Explain

Critical area: an area surrounded by certain symbols. For example, within {}.

The Enter and Exit methods of the Monitor object mark the beginning and end of the critical section.

After the Enter () method acquires the lock, it is guaranteed that only a single thread can use the code in the critical section. Using the Monitor class, it is best to use it with try {.} catch {.} finally {...}, because if the lock is acquired but the lock is not released, it will cause other threads to block infinitely, that is, a deadlock will occur.

Generally speaking, the lock keyword is enough.

Example

The following demonstrates how multiple threads can use Monitor to implement locks:

Private static object obj = new object (); private static bool acquiredLock = false; static void Main (string [] args) {new Thread (Test1). Start (); Thread.Sleep (1000); new Thread (Test2). Start () } public static void Test1 () {try {Monitor.Enter (obj, ref acquiredLock); for (int I = 0; I < 10; iTunes +) {Console.WriteLine ("Test1 is locking resources"); Thread.Sleep (1000) } catch {} finally {if (acquiredLock) Monitor.Exit (obj); Console.WriteLine ("Test1 has released resources");} public static void Test2 () {bool isGetLock = false Monitor.Enter (obj); try {Monitor.Enter (obj, ref acquiredLock); for (int I = 0; I < 10; iTunes +) {Console.WriteLine ("Test2 is locking resources"); Thread.Sleep (1000) }} catch {} finally {if (acquiredLock) Monitor.Exit (obj); Console.WriteLine ("Test2 has released resources");}} set the time limit for acquiring locks

If the object is already locked and another thread uses the Monitor.Enter object, it waits for another thread to unlock it.

But what if a thread has a problem or a deadlock, and the lock is locked all the time? Or is it meaningless for threads to be timed and not executed for more than a period of time?

We can set the wait time through Monitor.TryEnter (), and after a period of time, if the lock has not been released, it will return false.

The above example of modification is as follows:

Private static object obj = new object (); private static bool acquiredLock = false; static void Main (string [] args) {new Thread (Test1). Start (); Thread.Sleep (1000); new Thread (Test2). Start () } public static void Test1 () {try {Monitor.Enter (obj, ref acquiredLock); for (int I = 0; I < 10; iTunes +) {Console.WriteLine ("Test1 is locking resources"); Thread.Sleep (1000) } catch {} finally {if (acquiredLock) Monitor.Exit (obj); Console.WriteLine ("Test1 has released resources");} public static void Test2 () {bool isGetLock = false IsGetLock = Monitor.TryEnter (obj, 500); if (isGetLock = = false) {Console.WriteLine ("the lock is not released, I'm done"); return;} try {Monitor.Enter (obj, ref acquiredLock); for (int I = 0; I < 10) Thread.Sleep +) {Console.WriteLine ("Test2 is locking resources"); Thread.Sleep (1000);} catch {} finally {if (acquiredLock) Monitor.Exit (obj) Console.WriteLine ("Test2 has released resources");}} read here, this article "how to use lock and Monitor of C# multithread locks" has been introduced. If you want to master the knowledge points of this article, you still need to practice and use it before you can understand it. If you want to know more about related articles, welcome to follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report