In the previous blog, we began to learn about thread synchronization and Asynchronization. Many new students of self-taught students may be able to avoid this problem, which is actually very simple, next, let's talk to those who do not understand this concept aboutSomeoneAfter listening to the story, you will understand the truth in practice. (If a newbie gets a little bit from this article, it will also be a newbie, give me a message to know that I have not delayed your time. Of course, you can give me some constructive comments and guidance ).
What is thread synchronization?
When someone was in a mixed society,SomeoneThe first time I went to the jianghu to kill the game, I immediately met a snake,SomeoneIt was miserable to be hacked, and I was not given a chance to call a phone call. At this time, there were two routes for me.SomeoneChoose, do you want to get rid of your cell phone, do you want to continue carrying the result, the mobile phone cannot be pulled out, soSomeoneHas played a good tradition of cherishing life,SomeoneIt is hard to carry to the end. Now you understand what I am doing. Haha, this is synchronization. That is to say, you cannot do other things at the same time while doing one thing, otherwise, an accident will occur (that is, you have killed it ). This is the meaning of thread synchronization. Suppose multiple threads access a resource at the same time ,. the thread priority defined by net depends on the mood of the operating system. In addition, you should have the following concept: win32 thread scheduler and CLR allow threads to freely span the boundaries of application domains. However, at any point in time, multiple threads can exist in any application domain, however, a thread can only be executed in a specific application domain. That is to say, a thread cannot be executed simultaneously in multiple application domains at any time. This is a classic example. If you don't need to use multiple threads, you can use winfrom to run a large loop in it. (I drew a picture to demonstrate my superb artistic skills) (this program is simple but involves a cross-thread access issue. If you have time, go to the blog post to analyze it ).
You drag the program form, and you find that you are not strong enough to work, and you are still suffering from cultural loss, because the execution of this loop and the action you hold are all out of the same thread (in the main thread) and at the same time, if you drag it, it will crash, haha, now I understand. This is synchronization.
What is asynchronous now!
After the first lessonSomeoneI gave it to my younger brother, but the result is still more difficult. This time, I was confused,SomeoneDuring the recruitment process, I told the younger brother that you were about to call Lao Tzu for rescue. There were at least three trucks,SomeoneNo phone calls,SomeoneOnly tell the younger brother with specific information,SomeoneContinue to do what you want, and the younger brother will do it for me.SomeoneNo loss, orSomeoneI have finished the preparatory work in elementary school. I have done a few things at the same time, but I am still obedient to my younger brother,SomeoneSmile proudly. I'm afraid that it's not helpful. I'm afraid that it's annoying. This is asynchronous operations. Ajax's asynchronous mechanism is like this, so we can implement partial updates to webpages ...... now you should understand what Asp.net is.
In this series of blog posts, I don't plan to mention the thread priority and thread status. Let's take a look at these items. After all, they are secondary content and you will understand them at a glance.
. NET provides two methods to achieve synchronization, namely simple and advanced, which is nonsense. Haha, it is said. net1.0 also supports cross-process access to the thread, which will be disabled later. However, you can still cancel this unsafe access method by canceling an attribute of cross-process access, it's far away.
To continue, the simple method is polling and waiting, and the advanced method is to use synchronization objects.
What is round robin?
In fact, no one uses this method for low polling efficiency. The principle of this method is to listen to the thread state cyclically, and even if the thread is intercepted, it may be misjudged, suppose that when we use isalive to check whether a thread exits, we need to have such a concept that a thread in the active state is not necessarily running, that is, it may also be out of sleep state.
What is waiting?
The so-called waiting, Chinese-speaking children know that they are waiting for an object to do things. This is a lot of what I used in the previous blog, that is, join. Similarly, many younger siblings cannot understand what join is. Many articles have added such a call thread # ¥ % ...... The concept of this will make the children dizzy. There are still a lot of younger brothers in the group. In fact, you don't know what to do with that much, as I have already used a lot of Join Operations in the previous blog, I will not describe it here. The most common explanation is that the thread executes the join method, other threads must wait until the execution of the thread is complete. However, I will add here that this "execution is complete" is also relative, in case the sleep () method is called to sleep during the thread's execution, other threads may fail to execute, the CPU will allocate the time slice to other threads to execute their tasks until the thread wakes up again. Of course, since it is a simple problem, it can only solve simple logic. if the process is complicated, you should ask the engineers of mongogaiz to help you solve the thread synchronization problem with join. ^ @ ^! For specific examples, see the previous article.
Demo concurrency
After talking about this for a long time, we will first demonstrate the concurrent program to analyze the problems caused by concurrency. Next we will introduce the advanced methods to solve concurrency.
First, we have such a code. First, we post it for analysis.
1 using system; 2 using system. threading; 3 Public class printer 4 {5 Public void printnumbers () 6 {7 8 for (INT I = 0; I <10; I ++) 9 {10 random r = new random (); 11 thread. sleep (500 * r. next (3); 12 console. write ("{0},", I); 13} 14 console. writeline (); 15} 16 class program17 {18 static void main (string [] ARGs) 19 {20 console. writeline ("****** thread synchronization ***** \ n"); 21 22 printer P = new printer (); 23 24 Thread [] threads = new thread [10]; 25 for (INT I = 0; I <10; I ++) 26 {27 threads [I] = new thread (New threadstart (P. printnumbers); 28 threads [I]. name = string. format ("worker thread # {0} start execution! ", I); 29 console. writeline (threads [I]. name); 30} 31 foreach (thread t in threads) 32 t. start (); 33 console. readline (); 34} 35} 36}
At first glance, we certainly know that if we operate normally, we will certainly output 10 numbers each time in a loop, but the result is not our wishful thinking. Let's take a look: (Note: because the result of using a random function is only one of them)
As a result, we found that the result was not unexpected, Mao. Is it swollen? Why is it wrong?
Threads [I] = new thread (New threadstart (P. printnumbers ));
Let's look at this code. We found that every thread calls the printnumbers method of the same object P. Maybe this is just a clue,
Then let's look at this sentence again:Thread. Sleep (500 * R. Next (3 ));
We will find that the random thread suspension time is uncertain, and the possible situation is that when the printnumbers method is about to happen, the output is not yet
On the console, the current thread is suspended, and the Win32 thread scheduler switches the thread, so unexpected results are generated.
How can this problem be solved? haha, do you want to use the join above? There is nothing wrong with it? Let's try it first, but we need to introduce an advanced method,
Can we verify it with a low-level method? What is our idea? It is to wait until the current thread finishes executing the thread to run the next line.
Process. Let's test the code with a slight modification,
Let's just move our hands and feet here:
foreach (Thread t in threads) { t.Start(); t.Join(); }
But the results are different immediately, because we all know that every thread has been executed and the results are as expected:
So how can we use advanced methods to solve this problem?
In order to save time, we first make a simple lock method, which is actually generated to facilitate the use of the monitor class (completely equivalentMonitor class). I will explain it later. First, we only need to know how to solve these problems through advanced methods, but we still need to make the best choice. First, there will be a rough impact, and I will study it later in this blog post. It's impossible for me to finish writing it all at once. I have to attend classes and watch movies ....
First, let's explain the lock keyword. This keyword allows you to define a code Statement defined by a thread. Then, the entered thread does not interrupt the current thread, but is similar to implementing the join function, stop thread execution. Lock requires a tag (that is, the reference of an object). If you do not specify a tag, what should you do if you lock the door of another person? note O (Wait _ Wait) o ha! When the thread enters the lock range, it needs to get this mark. If you know that your door is locked and you cannot enter it, wait.
Of course, if we lock the private method of an instance object, this method can only be accessed by this object, then reference (that is, Mark) the object) the object reference of the method itself is OK. The simple point is this. the lock is your own door...
1 private void someprivatemethod () 2 {3 // use the current object as the lock mark 4 lock (this) 5 {6 // This statement block (range) the code in is thread-safe 7} 8}
The problem is that we have a lock, not all of which are their own doors. Maybe you are just looking at the door, haha. This problem arises. If you lock a piece of code from a public member, the recommended method of. NET is to useThe object is originally used as a lock tag. The so-called tag is so holy as you don't look at it. It is just an ID, it is only used for unique identification. Do not go into this issue.
1 private object mylock = new object (); 2 Public void printnumbers () 3 {4 // use the object member as the lock tag 5 lock (mylock) 6 {7... 8} 9} 10}
Well, after learning about this, we will start to solve the above problem. We analyzed that there may be problems in the thread suspension of each loop and the output part of the console. OK, then we lock it up, so we did this:
1 public void PrintNumbers() 2 { 3 lock (myLock) 4 { 5 for (int i = 0; i < 10; i++) 6 { 7 Random r = new Random(); 8 Thread.Sleep(500 * r.Next(3)); 9 Console.Write("{0}, ", i);10 }11 Console.WriteLine();12 }13 }
We can see the following results:
Facts have proved that we have mastered a little bit of basic knowledge about multi-thread concurrency..
Conclusion:
Multi-threading can leverage the advantages of our multi-core computers. Even the 02-year-old single-core Shaoyang notebook that I have used supports hyper-threading, but not all threads can be used at any time, it's like a more expensive Ferrari, you cannot get up in our mountain village, but if I drive a tractor on a high-speed road, it will be able to run, that is, it will be surrounded by people, so in my lifetime, my brother decided to launch a hummer, and the high-speed mountain village would be able to run for a while !! Joke, that is, you may not have to access more resources after multiple cores. Depending on the situation, multithreading is the correct decision.
If I help you when writing a blog, I will be able to support self-taught children, including me!