Detailed Explanation of the Usage of lock Keyword to Realize Thread Synchronization in C

  • 2021-11-01 04:19:58
  • OfStack

1. The lock keyword guarantees that a code block will not be disturbed by other threads during its execution, which is realized by imposing a mutex on a specific object during the running of the code block.

2. The arguments to the lock keyword must be objects of reference type. lock is not valid for basic data types such as int, long, etc., because the type it acts on must be an object. If long type data is passed in, it is bound to be converted to Int64 structure type, and the lock is a brand-new object reference. If you need to restrict mutually exclusive access to them, you can use the methods provided by the System. Threading. Interlocked class, which provides atomic operations.

3. Use lock (this) carefully. lock (this) is used in common types. If a new object is created and locked, it is easy to cause deadlock.

4. When locking an object of type ICollection, lock should have its SyncRoot property.

The SyncRoot attribute is declared in the interface ICollection, and its implementation varies.

For example, it is implemented in Collection (System. Collections. ObjectModel) as follows:


object ICollection.SyncRoot 
{ 
     get 
     { 
          if (this._syncRoot == null) 
          { 
               ICollection items = this.items as ICollection; 
               if (items != null) 
               { 
                    this._syncRoot = items.SyncRoot; 
               } 
               else 
               { 
                    Interlocked.CompareExchange(ref this._syncRoot, new object(), null); 
               } 
          } 
          return this._syncRoot; 
     } 
} 

And in List < T > , ArrayList, and so on


object ICollection.SyncRoot 
{ 
     get 
     { 
          if (this._syncRoot == null) 
          { 
               Interlocked.CompareExchange(ref this._syncRoot, new object(), null); 
          } 
          return this._syncRoot; 
     } 
} 
  

In the Array class, this is returned directly:


public object SyncRoot 
{ 
     get 
     { 
          return this; 
     } 
} 

5. The lock keyword is implemented with the Monitor (tube-side) class


lock(x) 
{ 
  DoSomething(); 
} 


System.Object obj = (System.Object)x; 
System.Threading.Monitor.Enter(obj); 
try 
{ 
  DoSomething(); 
} 
finally 
{ 
  System.Threading.Monitor.Exit(obj); 
} 

The above two pieces of code are equivalent. (MSDN)

Using the lock keyword is simpler and safer to use than the Monitor class.


Related articles: