157 recommendations for writing high-quality code to improve C # programs--recommendation 22: Ensure thread safety for collections

Source: Internet
Author: User

Recommendation 22: Ensure thread safety for collections

Collection thread security is when elements are added or removed on multiple threads, and the line Cheng must be kept in sync.

The following code simulates one thread during the iteration, and the other thread deletes the element.

    classProgram {Staticlist<person> list =NewList<person>()            {                NewPerson () {Name ="Rose", age = + },                NewPerson () {Name ="Steve", age = $ },                NewPerson () {Name ="Jessica", age = - },            }; StaticAutoResetEvent AutoSet =NewAutoResetEvent (false); Static voidMain (string[] args) {Thread T1=NewThread (() =            {                //Be sure to wait for T2 to start before running the following codeAutoset.waitone (); foreach(varIteminchlist) {Console.WriteLine ("T1:"+item.                    Name); Thread.Sleep ( +);            }            }); T1.            Start (); Thread T2=NewThread (() =            {                //notifies T1 that code can be executedAutoset.set (); //sleeps 1 seconds to ensure that the delete operation is in the T1 iterationThread.Sleep ( +); List. RemoveAt (2);            }); T2.        Start (); }    }    classPerson { Public stringName {Get;Set; }  Public intAge {Get;Set; } }

The above code will throw InvalidOperationException: "The collection has been modified and the enumeration may not be executed." ”

Before a generic collection appears, a non-generic collection typically provides a SyncRoot property that is guaranteed to be thread-safe for a non-generic collection, which can be implemented by locking the property. If the above collection is replaced with ArrayList, ensure that its thread safety should be added with lock when iterating and deleting, the code is as follows:

        StaticArrayList list =NewArrayList () {NewPerson () {Name ="Rose", age = + },                    NewPerson () {Name ="Steve", age = $ },                    NewPerson () {Name ="Jessica", age = - },        }; StaticAutoResetEvent AutoSet =NewAutoResetEvent (false); Static voidMain (string[] args) {Thread T1=NewThread (() =            {                //Be sure to wait for T2 to start before running the following codeAutoset.waitone (); Lock(list. SyncRoot) {foreach(Person iteminchlist) {Console.WriteLine ("T1:"+item.                        Name); Thread.Sleep ( +);            }                }            }); T1.            Start (); Thread T2=NewThread (() =            {                //notifies T1 that code can be executedAutoset.set (); //sleeps 1 seconds to ensure that the delete operation is in the T1 iterationThread.Sleep ( +); Lock(list. SyncRoot) {list. RemoveAt (2); Console.WriteLine ("Delete succeeded");            }            }); T2.        Start (); }

The above code does not throw an exception because the lock ensures that only one thread can manipulate the collection element at the same time by means of a mutually exclusive mechanism. We then find that the generic collection does not have such a property and must create a lock object on its own to complete the synchronization task. You can lock by a new static object, with the following code:

        Staticlist<person> list =NewList<person>()            {                NewPerson () {Name ="Rose", age = + },                NewPerson () {Name ="Steve", age = $ },                NewPerson () {Name ="Jessica", age = - },            }; StaticAutoResetEvent AutoSet =NewAutoResetEvent (false); Static ObjectSycobj =New Object(); Static voidMain (string[] args) {            //Object sycobj = new Object ();Thread T1 =NewThread (() =            {                //Be sure to wait for T2 to start before running the following codeAutoset.waitone (); Lock(sycobj) {foreach(Person iteminchlist) {Console.WriteLine ("T1:"+item.                        Name); Thread.Sleep ( +);            }                }            }); T1.            Start (); Thread T2=NewThread (() =            {                //notifies T1 that code can be executedAutoset.set (); //sleeps 1 seconds to ensure that the delete operation is in the T1 iterationThread.Sleep ( +); Lock(sycobj) {list. RemoveAt (2); Console.WriteLine ("Delete succeeded");            }            }); T2.        Start (); }

Turn from: 157 recommendations for writing high-quality code to improve C # programs Minjia

157 recommendations for writing high-quality code to improve C # programs--recommendation 22: Ensure thread safety for collections

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.