1. In a single thread, we can only do one thing at a time.
In multithreading, the most essential thing is that only one thing can be done at a time, but after the time slice specified by the CPU is completed, switch to another thread, and then after the CPU allocation time slice is completed, switching to another thread again and again, the switching speed is very fast, giving you the illusion of simultaneous operation.
However, in multithreading, two threads often occupy resources. Therefore, we need to prevent resource access conflicts.
C # thread synchronization mechanism is provided to prevent resource access conflicts. The lock keyword, Monitor class, And Mutex class are mainly used.
2. Thread Synchronization Mechanism
One advantage of multithreading in applications is that each thread can be executed asynchronously.
Thread Synchronization refers to the technology used by concurrent threads to efficiently and orderly access shared resources.
Synchronization means that only one thread can access resources at a certain time. Only when the resource owner voluntarily gives up the ownership of the code or resource can other threads use these resources.
3. Use the lock keyword to implement Thread Synchronization
The lock keyword can be used to ensure that the code block is run without being interrupted by other threads. It is implemented by obtaining mutex locks for a given object during the code block operation.
The lock statement starts with the keyword lock. It has an object as a parameter, and there is a code block that can only be executed by one thread at a time after this parameter.
Syntax format:
Object thisLock = new Object ();
Lock (thisLock) {// code block to run}
The parameter provided to the lock statement is only used to uniquely identify the resources shared by multiple threads, so any class instance can be used. In fact, this parameter usually identifies the resources to be synchronized by the thread.
Avoid locking the public type or the object instance that is not controlled by the application. Avoid locking public data types as much as possible. Locking strings is especially risky. Therefore, it is best to lock private or protected objects that are not temporarily stored.
Note: The lock statement is implemented using the Monitor class, which is equivalent to the try/finally statement block. Using the lock keyword is generally more desirable than directly using the Monitor class. First, the lock is more concise. Second, the lock ensures that the protected Code raises exceptions in time and can also release the basic listener. This is achieved through the finally keyword, whether or not a field is triggered, it executes the associated code block.
Note: If you use the lock keyword in a static method, you cannot use this
Static void Main (string [] args) {lock (new Program () {Console. WriteLine ("lock thread"); Console. ReadLine ();}}
4. Use the Monitor driver object for Thread Synchronization
The Monitor class provides a synchronous access mechanism to objects. It grants an object lock to a single thread to control access to objects. Object locks provide the ability to restrict access to code blocks (critical sections. When a thread has an object lock, no other thread can obtain the lock.
Main functions of the Monitor class:
(1) associate with an object as needed
(2) It is not bound and can be called directly from any context
(3) You cannot create a Monitor instance.
Common Methods of the Monitor class:
Enter gets the exclusive lock on the specified object
Exit to release the exclusive lock on the specified object
Pulse notifies the thread in the waiting queue of changing the status of the locked object.
PulseAll notifies all pending thread object status changes
TryEnter tries to obtain the exclusive lock of the specified object
Wait releases the lock on the object and blocks the current thread until it acquires the lock again.
Using the Monitor class to lock objects (reference type) rather than value types
Instance code:
Class Program {static void Main (string [] args) {Program myProgram = new Program (); // instantiate class Object myProgram. lockThread (); // call the Console of the locking thread method. readLine ();} void LockThread () {Monitor. enter (this); // lock the current thread Console. writeLine ("locking a thread to achieve thread synchronization"); Monitor. exit (this); // release the current thread }}
5. Use the Mutex class for Thread Synchronization
The Mutex class is similar to the monitor. Unlike the monitor, the Mutex class can be used for cross-process thread synchronization.
Use the WaitHandle. WaitOne method to request the ownership of the mutex
A thread with a mutex can request the same mutex in the repeated call to the WaitOne method without blocking its execution, but remember, the thread must call the ReleaseMutex method multiple times to release the ownership of the mutex.
Mutex class forced thread identification, so the Mutex can only be released by the thread that obtains it.
Common Mutex Methods
When Close is overwritten in a derived class, all resources held by the current WaitHandle are released.
OpenExisting open an existing named mutex
ReleaseMutex releases Mutex once
In the form of SignalAndWait atomic operations, send a signal to one WaitHandle and wait for another
WaitAll waits for all elements in the specified array to receive a signal
WaitAny waits for any element in the specified array to receive a signal
WaitOne is rewritten in the derived class to stop the current thread and know that the current WaitHandle receives the signal.
To synchronize Mutex threads:
1. Create a Mutex object. Common constructors include public Mutex (bool initallyOwned)
The parameter specifies whether the thread that creates the object wants to obtain its ownership immediately. When a Mutex object is created in a resource-protected class, this parameter is often set to false.
2. Call the wait method where a single thread is required to access the object and wait for the ownership of the Mutex object requested by the method. If the ownership is owned by another thread, the request thread will be blocked and put into the waiting queue. The request thread will remain congested, until the Mutex object is sent by its owner thread to release it.
6. instance code
Create a program, customize the lockThread method, use the WaitOne method of the Mutex object to block the current thread, and then call the ReleaseMutex method of the Mutex object to release the Mutex object, that is, release the current thread. Finally, the lockThread method is called through the object in the Main method.
Class Program {static void Main (string [] args) {Program myProgram = new Program (); // instantiate class Object myProgram. lockThread (); // call the Console of the locking thread method. readLine ();} void lockThread () {Mutex myMutex = new Mutex (false); // create the Mutex object myMutex. waitOne (); // block the current thread Console. writeLine ("locking a thread to achieve thread synchronization"); myMutex. releaseMutex (); // release a Mutex object }}
In general, the thread synchronization needs to be read several times to understand. In addition, we must constantly practice and exercise to know how the lock, Monitor and Mutex classes are used. What are their advantages and disadvantages.
I feel like I have no end to learning. Continue to Fighting.