Solution to multiple initialization problems in multiple threads

Source: Internet
Author: User

Solution to multiple initialization problems in multiple threads

Today, when I read the source code of the MSDN library, I found a class

 LazyInitializer.EnsureInitialized
Used in parallel computing.

MSdn code

// Used to hold any exceptions encountered during action processing                    ConcurrentQueue
 
   exceptionQ = null; // will be lazily initialized if necessary                     // This is more efficient for a large number of actions, or for enforcing MaxDegreeOfParallelism.                    try                    {                        // Launch a self-replicating task to handle the execution of all actions.                        // The use of a self-replicating task allows us to use as many cores                        // as are available, and no more.  The exception to this rule is                        // that, in the case of a blocked action, the ThreadPool may inject                        // extra threads, which means extra tasks can run.                        int actionIndex = 0;                        ParallelForReplicatingTask rootTask = new ParallelForReplicatingTask(parallelOptions, delegate                        {                            // Each for-task will pull an action at a time from the list                            int myIndex = Interlocked.Increment(ref actionIndex); // = index to use + 1                            while (myIndex <= actionsCopy.Length)                            {                                // Catch and store any exceptions.  If we don't catch them, the self-replicating                                // task will exit, and that may cause other SR-tasks to exit.                                // And (absent cancellation) we want all actions to execute.                                try                                {                                    actionsCopy[myIndex - 1]();                                }                                catch (Exception e)                                {                                    LazyInitializer.EnsureInitialized
  
   >(ref exceptionQ, () => { return new ConcurrentQueue
   
    (); });                                    exceptionQ.Enqueue(e);                                }                                 // Check for cancellation.  If it is encountered, then exit the delegate.                                if (parallelOptions.CancellationToken.IsCancellationRequested)                                    throw new OperationCanceledException(parallelOptions.CancellationToken);                                 // You're still in the game.  Grab your next action index.                                myIndex = Interlocked.Increment(ref actionIndex);                            }                        }, TaskCreationOptions.None, InternalTaskOptions.SelfReplicating);                         rootTask.RunSynchronously(parallelOptions.EffectiveTaskScheduler);                        rootTask.Wait();                    }                    catch (Exception e)                    {                        LazyInitializer.EnsureInitialized
    
     >(ref exceptionQ, () => { return new ConcurrentQueue
     
      (); });                         // Since we're consuming all action exceptions, there are very few reasons that                        // we would see an exception here.  Two that come to mind:                        //   (1) An OCE thrown by one or more actions (AggregateException thrown)                        //   (2) An exception thrown from the ParallelForReplicatingTask constructor                        //       (regular exception thrown).                        // We'll need to cover them both.                        AggregateException ae = e as AggregateException;                        if (ae != null)                        {                            // Strip off outer container of an AggregateException, because downstream                            // logic needs OCEs to be at the top level.                            foreach (Exception exc in ae.InnerExceptions) exceptionQ.Enqueue(exc);                        }                        else                        {                            exceptionQ.Enqueue(e);                        }                    }                     // If we have encountered any exceptions, then throw.                    if ((exceptionQ != null) && (exceptionQ.Count > 0))                    {                        ThrowIfReducableToSingleOCE(exceptionQ, parallelOptions.CancellationToken);                        throw new AggregateException(exceptionQ);                    }
     
    
   
  
 


The following content is reprinted to help you better understand the content above.

LazyInitializer. ensureInitialized is a new feature introduced by frameworks4.0. It implements the attribute delay initialization function and is used in System. in the Threading namespace, it is closely related to multithreading, that is, when many people use this method synchronously, it plays a role in the stored objects. This is related to msdn:

This method can be used by multiple executors to initialize the Target directory object.

When multiple executors access this method at the same time, multiple T execution individuals may be created, but only one execution individual will be stored to the target. In some cases, this method will not place unstored objects. If this type of object must be placed, the call end determines the failed object and places the object properly.

Synchronization with unclear concepts does not matter. See the example below for full understanding.

The following example describes the two initialization attributes and compares them. The advantage of delayed Initialization is that the object is initialized when it is used. In a method body, if an object is initialized once, do not perform repeated initialization.

Code 1 demonstrates poor performance

Code 2, showing the Optimization

Code 3: Microsoft encapsulates the program for us and performs better in multiple threads.

Code 1:

class TestLazyInitializer1    {        public People People        {            get            {                return new People();            }        }        public void Print1()        {            Console.WriteLine(People.Name);        }        public void Print2()        {            Console.WriteLine(People.Name);        }    }
Code 2:

class TestLazyInitializer2    {        People _people;        public People People        {            get            {                return _people == null                    ? (_people = new People())                    : _people;            }        }        public void Print1()        {            Console.WriteLine(People.Name);        }        public void Print2()        {            Console.WriteLine(People.Name);        }    }
Code 3

Class TestLazyInitializer {private People _ people ;////// Specify attributes for delayed initialization ///Public People {get {return LazyInitializer. ensureInitialized (ref _ people, () =>{ return new People () ;}) ;}} public void Print1 () {Console. writeLine (People. name);} public void Print2 () {Console. writeLine (People. name );}}

However, we can imagine the results of their running. When a class uses the same object multiple times, the performance is poor. The returned Name (current time) must be different, the returned Name (current time) must be a value if the performance is good and only initialized once.























Related Article

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.