Thread-Safe and threading-conflict solutions in the. NET object-oriented program design phase in threads for resource sharing; multithreading synchronization, using thread locks and thread notifications to implement threading synchronization, as described below:
1, threadstatic characteristics
Features: [ThreadStatic]
Function: Specifies that static fields have different values in different threads
Before we go, let's look at a multithreaded example:
We define a static field:
static int num = 0;
Then create two threads to add separately:
New Thread (() =>
{for
(int i = 0; i < 1000000; i++)
++num;
Console.WriteLine ("From {0}:{1}", Thread.CurrentThread.Name, num);
})
{Name = ' thread One '}. Start ();
New Thread (() =>
{for
(int i = 0; i < 2000000; i++)
++num;
Console.WriteLine ("From {0}:{1}", Thread.CurrentThread.Name, num);
})
{Name = ' thread Two '}. Start ();
Run multiple results as follows:
As you can see, the results of the three runs are different, and the problem arises because multiple threads share a resource at the same time, due to a synchronous sharing problem in multiple threads. The easiest way to solve the above problem is to use the ThreadStatic attribute of the static field.
When defining a static field, add the [threadstatic] attribute, as follows:
Copy Code code as follows:
[ThreadStatic]
static int num = 0;
Two threads unchanged, run again, the result is as follows:
No matter how many times it is run, the result is the same, and when the field is decorated with the threadstatic attribute, its value is different in each thread, that is, each thread will reallocate the memory space for the static field, and of course, the new operation, There is no problem with the static field.
2. Resource Sharing
Multi-threaded resource sharing, that is, multi-threaded synchronization (that is, resource synchronization), it should be noted that thread synchronization refers to the resource synchronization that the thread accesses, not the synchronization of the thread itself.
During the actual use of multithreading, not all threads access different resources.
Let's look at a threading example, and if we don't know how long the thread is going to finish, we wait for a fixed time (if it's 500 milliseconds):
Define a static field first:
static int result;
To create a thread:
Thread mythread = new Thread (() =>
{
thread.sleep (1000);
result = N;
});
Mythread.start ();
Thread.Sleep ();
Console.WriteLine (result);
The results of the operation are as follows:
You can see that the result is 0, obviously not what we want, but often in the course of the thread execution, we do not know how long it will be completed, can not be a thread after the completion of a notice?
There are a lot of stupid ways, such as we might think of using a loop to detect thread state, which are not ideal.
. NET provides us with a join method, that is, thread blocking, can solve the above problem, we use stopwatch to remember,
The improved threading code is as follows:
System.Diagnostics.Stopwatch watch = System.Diagnostics.Stopwatch.StartNew ();
Thread mythread = new Thread (() =>
{
thread.sleep (1000);
result = N;
});
Mythread.start ();
Thread.Sleep ();
Mythread.join ();
Console.WriteLine (watch. Elapsedmilliseconds);
Console.WriteLine (result);
The results of the operation are as follows:
The result is consistent with what we want.
3. Thread Lock
In addition to the method above, for thread synchronization. NET also provides us with a lock mechanism to resolve the synchronization, and again improve the example below:
First define a static field to store the lock:
Static object locker = new Object ();
Here we can start without thinking about what this object is. Continue to look at the improved thread:
System.Diagnostics.Stopwatch watch = System.Diagnostics.Stopwatch.StartNew ();
thread T1 = new Thread (() =>
{
lock (locker)
{
thread.sleep (1000);
result =;
}
});
T1. Start ();
Thread.Sleep (m);
Lock (Locker)
{
Console.WriteLine ("Thread Time consuming:" +watch.) Elapsedmilliseconds);
Console.WriteLine ("Thread output:" +result);
}
The results of the operation are as follows:
Run results as in the example above, if the threading process is more complex, you can see a significant reduction in time consuming, which completes thread synchronization in a more efficient way than blocking.
4. Thread notification
It says here that you can notify the waiting thread when a thread is finished, here. NET provides us with an event notification method to solve this problem.
4.1 AutoResetEvent
Define a Notification object first
Copy Code code as follows:
static EventWaitHandle tellMe = new AutoResetEvent (false);
The above threads are improved as follows:
System.Diagnostics.Stopwatch watch = System.Diagnostics.Stopwatch.StartNew ();
Thread mythread = new Thread (() =>
{
thread.sleep (1000);
result = m;
Tellme.set ();
});
Mythread.start ();
Tellme.waitone ();
Console.WriteLine ("Thread Time consuming:" + watch.) Elapsedmilliseconds);
Console.WriteLine ("Thread output:" + result);
The results of the operation are as follows:
4.2 ManualResetEvent
And AutoResetEvent also has a ManualResetEvent manual mode, their difference is that the thread after the end of the ManualResetEvent can still pass, unless manually reset closed. Let's look at an example:
First define an object for manual notification:
static EventWaitHandle mre = new ManualResetEvent (false);
To create a thread:
System.Diagnostics.Stopwatch watch = System.Diagnostics.Stopwatch.StartNew ();
Thread Mythreadfirst = new Thread (() =>
{
thread.sleep (1000);
result = m;
MRe. Set ();
}) {Name = ' thread One '};
Thread Mythreadsecond = new Thread (() =>
{
mre. WaitOne ();
Console.WriteLine (Thread.CurrentThread.Name + "Get results: + result +" ("+system.datetime.now.tostring () +"));
} {name= "thread Two"};
Mythreadfirst.start ();
Mythreadsecond.start ();
MRe. WaitOne ();
Console.WriteLine ("Thread Time consuming:" + watch.) Elapsedmilliseconds + "(" + System.DateTime.Now.ToString () +) ");
Console.WriteLine ("Thread output: + result +" ("+ System.DateTime.Now.ToString () +"));
The results of the operation are as follows:
4.3. Semaphore
Semaphore is also a kind of thread notification, the above notification mode, the number of threads open in a lot of cases, the use of Reset () closed, if you do not use sleep hibernate, it is likely to cause some threads do not recover the case, a thread early shutdown, for this difficult to predict the situation, . NET provides a higher level of notification semaphore, which can guarantee that the problem does not occur during Hyper-threading.
Define a static field for the notification object first:
Copy Code code as follows:
static semaphore sem = new semaphore (2, 2);
To create 100 threads using a loop:
for (int i = 1; I <= i++)
{
new Thread (() =>
{sem)
. WaitOne ();
Thread.Sleep (a);
Console.WriteLine (thread.currentthread.name+ "" +datetime.now.tostring ());
Sem. Release ();
}) {name= "thread" +i}. Start ();
}
The results of the operation are as follows:
Can see the full output we want to see the results.
5. The main points of this section are:
A. The threadstatic attribute of a static field in a thread that uses this field to have different values in different threads
B. Several ways of thread synchronization, lock and thread notifications
C. Two ways to Thread notifications: Autoresetevent/manualresetevent and semaphore
This is the end of. NET object-oriented multithreading (multithreading) and multithreaded advanced application introduction so far.