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

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

  • 相关阅读:
    Spring Data JPA简介 Spring Data JPA特点
    JavaScript的事件循环机制总结 eventLoop
    什么是 MyBatis?
    如果你也用过 struts2.简单介绍下 springMVC 和 struts2 的区别有哪些?
    SpringMvc 框架
    线程、并发、并行、进程是什么,以及如何开启新的线程?
    面试:你最大的长处和弱点分别是什么?这些长处和弱点对你在企业的业绩会有什么样的影响?
    面向对象三大特性
    一台客户端有三百个客户与三百个客户端有三百个客户对服务器施压,有什么区别?
    面向对象三大特性
  • 原文地址:https://www.cnblogs.com/malaikuangren/p/2532270.html
Copyright © 2011-2022 走看看