Multithreading problem and double-check

Source: Internet
Author: User

In a multithreaded program, if a shared resource is used by multiple threads at the same time, it can cause a multi-threaded problem, depending on whether an operation on that resource is thread-safe. For example. NET dictionary is a completely thread insecure data structure, for dictionary insert, delete can lead to multi-threading problems, mainly because dictionary internal implementation structure will be frequently due to insert, delete operation and change the length, at this time, In the event of multithreading problems, the program is most likely to throw an array out of bounds exception. In particular, for WebService, each request generates a thread/instance, so pay special attention to multithreading issues.

In general, multithreading issues often occur in conjunction with shared resources. For example, for the use of member variables of a class, for the use of global static variables, and for local variables inside a function, there is no multithreading problem for the generic, because each thread generates a copy of the function's internal member variables when invoking a particular function, and the threads and threads are mutually irrelevant.
The most common way to solve a multithreaded problem is to lock it so that a resource can only be used by one thread at a time, while other threads must wait outside the locked code until the lock is lifted, as shown in the following C # code:

1             Lock (_lock) 2             {3                 //do something to theshared resources. 4             }

Let's talk about double-check.
Multithreading problems are often associated with a lazy-initialize design pattern. Here it will slowly lead to double-check. Lazy-initialize, for some particularly complex objects, let the program initialize it the first time it is called, and it is guaranteed to be initialized only once.
The first design to think of is this:

1     classA2     {3 4 5         PrivateComplexclass _result =NULL;6 7          Publiccomplexclass GetResult ()8         {9             if(_result = =NULL)Ten             { One_result =NewComplexclass (); A             } -             return_result; -         } the}

But there's a problem with that. When the Complexclass is constructed longer, _result may be null when the first thread is still in the Complexclass construct, or it may point to an object that has not yet been initialized. This way, either two threads initialize the Complexclass two times, or the second thread returns a reference to an incomplete object. Therefore, a lock is required here, as shown below:

1 complexclass GetResult ()2         {3             Lock(_lock)4             {5                 if(_result = =NULL)6                 {7_result =NewComplexclass ();8                 }9             }Ten             return_result; One}

This way, although a multi-threaded problem is resolved, a lock is requested every time a result is required, and the request lock has a significant impact on the performance of the program, so we add a check to the outside of Lock:

1 complexclass GetResult ()2         {3             if(_result = =NULL)4             {5                 Lock(_lock)6                 {7                     if(_result = =NULL)8                     {9_result =NewComplexclass ();Ten                     } One                 } A             } -             return_result; -}

In this way, for all requests after initialization, no lock is requested, but the _result is returned directly.
But there is still a little problem. For some programming languages, _result = new Complexclass (); This code causes _result to point to a partially initialized object. That is, when thread a initializes the Complexclass, thread B may be able to determine that _result is not NULL, but when initialization is not yet complete, then thread B directly returns a partially initialized object, causing the program to crash. So, how do we solve this problem? The general solution is to add a buffer inside the program with a local variable (identity variable):

1 complexclass GetResult ()2         {3 complexclass result;4             if(_result = =NULL)5             {6                 Lock(_lock)7                 {8                     if(_result = =NULL)9                     {Tenresult =NewComplexclass (); One_result =result; A                     } -                 } -             } the             return_result; -}

In this way, the above problem is completely solved ~

Multithreading problem and double-check

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.