• ThreadSafety Mutex vs Lock(Synchronization of .net)


    Mutex

    A Mutex works in much the same way as the lock statement (that we will look at in the Critical sections section below), so I won't harp on about it too much. But the main advantage the Mutex has over lock statements and theMonitor object is that it can work across multiple processes, which provides a computer-wide lock rather than application wide.

    Sasha Goldshtein, the technical reviewer of this article, also stated that when using a Mutex, it will not work over Terminal Services.

    Application Single Instance

    One of the most common uses of a Mutex is, unsurprisingly, to ensure that only one instance of an application is actually running

    Let's see some code. This code ensures a single instance of an application. Any new instance will wait 5 seconds (in case the currently running instance is in the process of closing) before assuming there is already a previous instance of the application running, and exiting.

    using System;
    using System.Threading;

    namespace MutexTest
    {
        class Program
        {
            //start out with un-owned mutex
            static Mutex mutex = new Mutex(false,"MutexTest");

            static void Main(string[] args)
            {
                //check to see if there is another instance, allow 5 secs
                //another instance may be in process of closing right now
                if(!mutex.WaitOne(TimeSpan.FromSeconds(5)))
                {
                    Console.WriteLine("MutexTest already running! Exiting");
                    return;
                }
                try
                {
                    Console.WriteLine("MutexTest Started");
                    Console.ReadLine();
                }
                finally
                {
                    //release the mutx to allow, possible future instance to run
                    mutex.ReleaseMutex();
                }
            }
        }

    }

    So if we start an instance of this app, we get the message text in the console window: 

    "MutexTest Started" 
    When we try and run another copy, we get the following (after a 5 second delay): 
    "MutexTest already running! Exiting" 

    Lock

    by the use of the lockkeyword. Only one thread can lock the synchronizing object (syncLock, in this case) at a time. Any contending threads are blocked until the lock is released. And contending threads are held in a "ready queue", and will be given access on a first come first served basis.

    Some people use lock(this) or lock(typeof(MyClass)) for the synchronization object. Which is a bad idea as both of these are publicly visible objects, so theoretically, an external entity could use them for synchronization and interfere with your threads, creating a multitude of interesting problems. So it's best to always use a private synchronization object.

    I now want to briefly talk about the different ways in which you can lock  

    Other ways of doing "Lock" job

    MethodImpl.Synchronized attribute

    he last method relies on the use of an attribute which you can use to adorn a method to say that it should be treated as synchronized. Let's see this: 

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace MethodImplSynchronizedTest
    {
        /// <summary>
        /// This shows how to create a critical section
        /// using the System.Runtime.CompilerServices.MethodImplAttribute
        /// </summary>
        class Program
        {
            static int item1=54, item2=21;

            static void Main(string[] args)
            {
                //make a call to different method
                //as cant Synchronize Main method
                DoWork();
            }

            [System.Runtime.CompilerServices.MethodImpl
            (System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]
            private static void DoWork()
            {
                if (item1 != 0)
                    Console.WriteLine(item1 / item2);
                item2 = 0;
                Console.ReadLine();
            }
        }

    }

    This simple example shows that you can use System.Runtime.CompilerServices.MethodImplAttribute to mark a method as synchronized (critical section).

    One thing to note is that if you lock a whole method, you are kind of missing the chance for better concurrent programming, as there will not be that much better performance than that of a single threaded model running the method. For this reason, you should try to keep the critical sections to be only around fields that need to be safe across multiple threads. So try and lock when you read/write to common fields.

    Of course, there are some occasions where you may need to mark the entire method as a critical section, but this is your call. Just be aware that locks should generally be as small (granularity) as possible. 

    SynchronizationAttribute

    该属性可作用在一个类上描述。目的是为了同步上下文,一样可以达到同步代码的作用 。 

  • 相关阅读:
    二叉查找树
    Rust更换Crates源
    Raft共识算法
    Session
    可以编写代码的代码:代码生成的利与弊
    引用和自包含令牌(Reference Tokens and Introspection)
    认证授权-学习笔记1-OAuth 2.0
    spring security原理-学习笔记2-核心组件
    spring security原理-学习笔记1-整体概览
    零拷贝Zero copy-linux and java
  • 原文地址:https://www.cnblogs.com/malaikuangren/p/2532270.html
Copyright © 2020-2023  润新知