C # Multithreaded programming step two-thread synchronization and thread safety

Source: Internet
Author: User

The previous blog learned how to use multithreading in a simple way. In fact, the common multithreading is really simple, but a safe and efficient multithreading is not so simple. So many times improper use of multithreading will affect the performance of the program.

Let's look at an example below:

classProgram {Static intnum =1; Static voidMain (string[] args) {Stopwatch Stopwatch=NewStopwatch (); //Start TimingStopwatch.start (); ThreadStart ThreadStart=NewThreadStart (Run);  for(inti =0; I <5; i++) {thread thread=NewThread (ThreadStart); Thread.            Start (); } num++; Console.WriteLine ("num is:"+num); Console.WriteLine ("Main thread ID is:"+Thread.CurrentThread.ManagedThreadId.ToString ()); //Stop TimingStopwatch.stop (); //time of output execution, number of millisecondsConsole.WriteLine ("The execution time is"+ Stopwatch.elapsedmilliseconds +"milliseconds.");        Console.readkey (); }         Public Static voidRun () {num++; Console.WriteLine ("num is:"+num); Console.WriteLine ("Child Thread ID is:"+Thread.CurrentThread.ManagedThreadId.ToString ()); }    }

Execution Result:

It can be seen from the above that the value of the variable num is not continuous increment, the output is not sequential, and the value of each output is not the same, because the asynchronous thread accesses a member at the same time, so this multithreading for us is not controllable. The above example is non-thread-safe, so thread-safe requires thread synchronization. There are many ways to thread synchronization, such as the Join () method that was used before, and it can also implement thread synchronization. Let's try it out here:

classProgram {Static intnum =1; Static voidMain (string[] args) {Stopwatch Stopwatch=NewStopwatch (); //Start TimingStopwatch.start (); ThreadStart ThreadStart=NewThreadStart (Run);  for(inti =0; I <5; i++) {thread thread=NewThread (ThreadStart); Thread.                Start (); Thread.            Join (); } num++; Console.WriteLine ("num is:"+num); Console.WriteLine ("Main thread ID is:"+Thread.CurrentThread.ManagedThreadId.ToString ()); //Stop TimingStopwatch.stop (); //time of output execution, number of millisecondsConsole.WriteLine ("The execution time is"+ Stopwatch.elapsedmilliseconds +"milliseconds.");        Console.readkey (); }         Public Static voidRun () {num++; Console.WriteLine ("num is:"+num); Console.WriteLine ("Child Thread ID is:"+Thread.CurrentThread.ManagedThreadId.ToString ()); }    }

Execution Result:

This allows for simple synchronization, which adds a single line of code (thread) compared to the code above. Join ();), which previously referred to join () This method is used to block the current thread until the previous thread finishes executing. However, although this is achieved synchronization, but also blocked the continuation of the main thread to execute, so and single-threaded seemingly no difference. So let's learn some other ways.

There is also a locking mechanism for thread synchronization, and the following is the simplest locking mechanism that uses lock. As follows:

classProgram {Private ObjectLocker =New Object(); intnum =1; Static voidMain (string[] args) { Program Program=NewProgram (); Stopwatch Stopwatch=NewStopwatch (); //Start TimingStopwatch.start (); ThreadStart ThreadStart=NewThreadStart (program.            Run);  for(inti =0; I <5; i++) {thread thread=NewThread (ThreadStart); Thread.            Start (); } program.num++; Console.WriteLine ("num is:"+program.num); Console.WriteLine ("Main thread ID is:"+Thread.CurrentThread.ManagedThreadId.ToString ()); //Stop TimingStopwatch.stop (); //time of output execution, number of millisecondsConsole.WriteLine ("The execution time is"+ Stopwatch.elapsedmilliseconds +"milliseconds.");        Console.readkey (); }         Public voidRun () {Lock(locker) {num++; Console.WriteLine ("num is:"+num); Console.WriteLine ("Child Thread ID is:"+Thread.CurrentThread.ManagedThreadId.ToString ()); }        }    }

Execution Result:

Lock is a simple and easy way to synchronize threads by acquiring mutexes for a given object. You can see that this way does not block the main thread, and the value of the member variable is continuously incremented, which means that it is thread-safe. The lock lock mechanism means that only one thread at a time can lock the synchronization object (here is locker), and any other competing threads will be blocked until the lock is released.

The parameter of lock must be based on the reference type of the object, not the basic type, such as bool, int, so it is not synchronous at all, because the parameter of lock is an object, if the incoming int, it is bound to take place boxing operation, so each lock will be a new different object. It is best to avoid using the public type or an object instance that is not controlled by the program because it is likely to cause deadlocks. Never lock a string.

Get here for the time being, and learn other ways to continue updating later.

C # Multithreaded programming step two-thread synchronization and thread safety

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.