zoukankan      html  css  js  c++  java
  • 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

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

  • 相关阅读:
    The 4 Most Important Skills for a Software Developer
    Youth is not a time of life, it is a state of mind——青春不是一段年华,而是一种心境
    英雄所见略同——每个人都有的一套价值体系观念
    28法则————10分钟休息胜过半小时努力
    离职员工心声
    员工必备素质、能力——职场精英
    安卓sqlite数据库的使用
    安卓adb命令的使用
    windows使用命令行,提高效率
    命令行编译java文件(含第三方jar包)
  • 原文地址:https://www.cnblogs.com/malaikuangren/p/2532270.html
Copyright © 2011-2022 走看看